557 lines
28 KiB
JSON
557 lines
28 KiB
JSON
{
|
||
"name": "astra",
|
||
"displayName": "Astra",
|
||
"description": "The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.",
|
||
"version": "2.2.18",
|
||
"publisher": "g1nation",
|
||
"license": "MIT",
|
||
"icon": "assets/icon.png",
|
||
"repository": {
|
||
"type": "git",
|
||
"url": "https://github.com/g1nations/locallm"
|
||
},
|
||
"engines": {
|
||
"vscode": "^1.80.0"
|
||
},
|
||
"categories": [
|
||
"Machine Learning",
|
||
"Programming Languages",
|
||
"Chat"
|
||
],
|
||
"keywords": [
|
||
"ai",
|
||
"local",
|
||
"ollama",
|
||
"gemma",
|
||
"llama",
|
||
"deepseek",
|
||
"offline",
|
||
"agent",
|
||
"code-generation",
|
||
"astra",
|
||
"copilot"
|
||
],
|
||
"activationEvents": [
|
||
"onStartupFinished"
|
||
],
|
||
"main": "./out/extension.js",
|
||
"contributes": {
|
||
"commands": [
|
||
{
|
||
"command": "g1nation.newChat",
|
||
"title": "Astra: New Chat",
|
||
"icon": "$(add)"
|
||
},
|
||
{
|
||
"command": "g1nation.exportChat",
|
||
"title": "Astra: Export Chat as Markdown"
|
||
},
|
||
{
|
||
"command": "g1nation.explainSelection",
|
||
"title": "Astra: Explain Selected Code"
|
||
},
|
||
{
|
||
"command": "g1nation.focusChat",
|
||
"title": "Astra: Focus Chat Input"
|
||
},
|
||
{
|
||
"command": "g1nation.showBrainNetwork",
|
||
"title": "Astra: Show Brain Topology"
|
||
},
|
||
{
|
||
"command": "g1nation.approval.focus",
|
||
"title": "Astra: Focus Approval Panel"
|
||
},
|
||
{
|
||
"command": "g1nation.scaffoldProject",
|
||
"title": "Astra: Scaffold New Project"
|
||
},
|
||
{
|
||
"command": "g1nation.telegram.setBotToken",
|
||
"title": "Astra: Set Telegram Bot Token"
|
||
},
|
||
{
|
||
"command": "g1nation.telegram.clearBotToken",
|
||
"title": "Astra: Clear Telegram Bot Token"
|
||
},
|
||
{
|
||
"command": "g1nation.telegram.testConnection",
|
||
"title": "Astra: Test Telegram Connection"
|
||
},
|
||
{
|
||
"command": "g1nation.settings.focus",
|
||
"title": "Astra: Open Settings Panel"
|
||
},
|
||
{
|
||
"command": "g1nation.skills.editKnowledgeMap",
|
||
"title": "Astra: Edit Agent ↔ Knowledge Map"
|
||
},
|
||
{
|
||
"command": "g1nation.openChat",
|
||
"title": "Astra: Open Chat (Editor Column)",
|
||
"icon": "$(comment-discussion)"
|
||
},
|
||
{
|
||
"command": "g1nation.lesson.create",
|
||
"title": "Astra: New Lesson (Experience Memory)"
|
||
},
|
||
{
|
||
"command": "g1nation.lesson.fromConversation",
|
||
"title": "Astra: New Lesson from Current Conversation"
|
||
},
|
||
{
|
||
"command": "g1nation.lesson.manage",
|
||
"title": "Astra: Browse / Manage Lessons"
|
||
},
|
||
{
|
||
"command": "g1nation.architecture.refresh",
|
||
"title": "Astra: Refresh Project Architecture Context"
|
||
},
|
||
{
|
||
"command": "g1nation.architecture.detach",
|
||
"title": "Astra: Detach Project Architecture Context"
|
||
},
|
||
{
|
||
"command": "g1nation.architecture.attach",
|
||
"title": "Astra: Attach Project Architecture Context"
|
||
},
|
||
{
|
||
"command": "g1nation.architecture.open",
|
||
"title": "Astra: Open Project Architecture Doc"
|
||
},
|
||
{
|
||
"command": "g1nation.company.toggle",
|
||
"title": "Astra: Toggle 1인 기업 Mode"
|
||
},
|
||
{
|
||
"command": "g1nation.company.manage",
|
||
"title": "Astra: Manage 1인 기업 Agents"
|
||
},
|
||
{
|
||
"command": "g1nation.company.openSessions",
|
||
"title": "Astra: Open 1인 기업 Sessions Folder"
|
||
},
|
||
{
|
||
"command": "g1nation.company.pixelOffice.open",
|
||
"title": "Astra: Open Pixel Office (Full Screen)"
|
||
},
|
||
{
|
||
"command": "g1nation.calendar.connect",
|
||
"title": "Astra: Google Calendar (iCal) 연결 📅"
|
||
},
|
||
{
|
||
"command": "g1nation.calendar.refresh",
|
||
"title": "Astra: Google Calendar 새로고침 📅"
|
||
},
|
||
{
|
||
"command": "g1nation.calendar.connectOAuth",
|
||
"title": "Astra: Google Calendar OAuth 연결 (쓰기) 🔐"
|
||
}
|
||
],
|
||
"keybindings": [
|
||
{
|
||
"command": "g1nation.focusChat",
|
||
"key": "cmd+l",
|
||
"mac": "cmd+l"
|
||
}
|
||
],
|
||
"menus": {
|
||
"editor/context": [
|
||
{
|
||
"command": "g1nation.explainSelection",
|
||
"when": "editorHasSelection",
|
||
"group": "1_modification"
|
||
}
|
||
]
|
||
},
|
||
"viewsContainers": {
|
||
"activitybar": [
|
||
{
|
||
"id": "astra-activity",
|
||
"title": "Astra",
|
||
"icon": "assets/icon-activitybar.svg"
|
||
}
|
||
]
|
||
},
|
||
"views": {
|
||
"astra-activity": [
|
||
{
|
||
"id": "astra-launcher",
|
||
"name": "Astra Launcher"
|
||
}
|
||
]
|
||
},
|
||
"viewsWelcome": [
|
||
{
|
||
"view": "astra-launcher",
|
||
"contents": "✦ **Astra** — 로컬 AI 인텔리전스 레이어\n\nChat 탭을 닫았을 때 여기서 다시 열 수 있습니다.\n\n[$(comment-discussion) Open Chat](command:g1nation.openChat)\n[$(add) New Chat](command:g1nation.newChat)\n[$(gear) Settings](command:g1nation.settings.focus)\n\n---\n\n**1인 기업 모드**\n\n[$(organization) Manage Agents](command:g1nation.company.manage)\n[$(folder-opened) Open Sessions Folder](command:g1nation.company.openSessions)\n\n---\n\n**Project Architecture**\n\n[$(file-text) Open Architecture Doc](command:g1nation.architecture.open)\n[$(refresh) Refresh Architecture](command:g1nation.architecture.refresh)\n\n---\n\n**Lessons / Knowledge**\n\n[$(lightbulb) Manage Lessons](command:g1nation.lesson.manage)\n[$(edit) Edit Agent ↔ Knowledge Map](command:g1nation.skills.editKnowledgeMap)"
|
||
}
|
||
],
|
||
"configuration": {
|
||
"title": "Astra",
|
||
"properties": {
|
||
"g1nation.multiAgentEnabled": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "Enable Multi-Agent Workflow (Planner -> Researcher -> Writer) for complex tasks."
|
||
},
|
||
"g1nation.memoryEnabled": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Enable layered memory injection before each model response."
|
||
},
|
||
"g1nation.memoryShortTermMessages": {
|
||
"type": "number",
|
||
"default": 8,
|
||
"minimum": 0,
|
||
"description": "Number of recent conversation messages included as short-term memory."
|
||
},
|
||
"g1nation.memoryMediumTermSessions": {
|
||
"type": "number",
|
||
"default": 5,
|
||
"minimum": 0,
|
||
"description": "Number of recent saved chat sessions included as medium-term memory."
|
||
},
|
||
"g1nation.memoryLongTermFiles": {
|
||
"type": "number",
|
||
"default": 6,
|
||
"minimum": 0,
|
||
"description": "Number of relevant Second Brain markdown files included as long-term memory."
|
||
},
|
||
"g1nation.ollamaUrl": {
|
||
"type": "string",
|
||
"default": "http://127.0.0.1:11434",
|
||
"description": "Base URL for Ollama or LM Studio. Default: http://127.0.0.1:11434"
|
||
},
|
||
"g1nation.defaultModel": {
|
||
"type": "string",
|
||
"default": "gemma4:e2b",
|
||
"description": "Default model name to use for chat requests."
|
||
},
|
||
"g1nation.requestTimeout": {
|
||
"type": "number",
|
||
"default": 300,
|
||
"description": "Request timeout in seconds. Default: 300"
|
||
},
|
||
"g1nation.contextLength": {
|
||
"type": "number",
|
||
"default": 32768,
|
||
"minimum": 2048,
|
||
"description": "Model context window in tokens (prompt + generation combined). Set this to the value your loaded model is actually running with in LM Studio / Ollama. Astra budgets prompt and output against this so it never overflows. Default: 32768"
|
||
},
|
||
"g1nation.maxOutputTokens": {
|
||
"type": "number",
|
||
"default": 4096,
|
||
"minimum": 256,
|
||
"description": "Upper bound on tokens generated per response. The effective limit is reduced automatically when the prompt is large so input + output stays within g1nation.contextLength. Default: 4096"
|
||
},
|
||
"g1nation.contextSafetyMargin": {
|
||
"type": "number",
|
||
"default": 2048,
|
||
"minimum": 0,
|
||
"description": "Tokens kept free as a safety buffer for token-count estimation error. Default: 2048"
|
||
},
|
||
"g1nation.contextOverflowPolicy": {
|
||
"type": "string",
|
||
"enum": [
|
||
"stopAtLimit",
|
||
"truncateMiddle",
|
||
"rollingWindow"
|
||
],
|
||
"default": "stopAtLimit",
|
||
"description": "Fallback behavior (LM Studio) if the prompt still exceeds the context window after Astra's own budgeting. 'stopAtLimit' fails clearly so you notice; 'truncateMiddle'/'rollingWindow' drop content silently. Default: stopAtLimit"
|
||
},
|
||
"g1nation.autoCompactHistory": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Automatically drop the oldest conversation messages from the request when the prompt would exceed the context budget (the on-screen chat history is unaffected). Default: true"
|
||
},
|
||
"g1nation.smallModelContextCap": {
|
||
"type": "number",
|
||
"default": 0,
|
||
"minimum": 0,
|
||
"description": "Optional safety knob, OFF by default (0). Some very small models (≤3B) emit an empty/EOS response when given a prompt near their context window even though it nominally fits. If you observe that with a tiny model, set this to e.g. 8192–16384: for ≤3B models only, Astra then budgets the prompt against this smaller effective window instead of g1nation.contextLength. Never applies to 4B+ models. Leave 0 unless you actually hit the issue — it reduces the output-token budget. Default: 0 (disabled)"
|
||
},
|
||
"g1nation.autoContinueOnOutputLimit": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "When a reply is cut off because it hit the output-token limit, Astra continues it internally (compressed request — original question + the answer so far, not the whole context again) and shows one merged answer, instead of asking you to say \"이어서 작성해줘\". Default: true"
|
||
},
|
||
"g1nation.maxAutoContinuations": {
|
||
"type": "number",
|
||
"default": 4,
|
||
"minimum": 0,
|
||
"maximum": 10,
|
||
"description": "Maximum number of automatic continuation rounds per reply (prevents runaway loops). Raise it (e.g. 5–6) for long-form answers on slow local models; set 0 to disable auto-continuation. Default: 4"
|
||
},
|
||
"g1nation.finalOnlyRetryOnThoughtLeak": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "If the model emits only hidden reasoning (<think>, <|channel|>thought, \"Thinking Process:\" …) and no user-visible answer, Astra silently re-asks it for the final answer only. Hidden reasoning is never shown either way. Default: true"
|
||
},
|
||
"g1nation.lmStudio.idleTimeoutMs": {
|
||
"type": "number",
|
||
"default": 300000,
|
||
"minimum": 0,
|
||
"description": "Auto-eject the loaded LM Studio model after this many milliseconds of inactivity. Set to 0 to disable. Default: 300000 (5 minutes)."
|
||
},
|
||
"g1nation.lmStudio.autoLoadOnSelect": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Automatically load LM Studio models into memory when selected from the Astra sidebar."
|
||
},
|
||
"g1nation.localBrainPath": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Folder path for your local Second Brain knowledge base. Leave empty to use the default folder."
|
||
},
|
||
"g1nation.brainProfiles": {
|
||
"type": "array",
|
||
"default": [],
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "string",
|
||
"description": "Stable brain profile id."
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "Display name shown in the Astra brain selector."
|
||
},
|
||
"localBrainPath": {
|
||
"type": "string",
|
||
"description": "Local folder path used as this brain's markdown knowledge base."
|
||
},
|
||
"secondBrainRepo": {
|
||
"type": "string",
|
||
"description": "Optional Git repository URL for this brain."
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"description": "Short note shown under the active brain status."
|
||
}
|
||
}
|
||
},
|
||
"description": "Multiple brain profiles. Each item supports id, name, localBrainPath, secondBrainRepo, and description."
|
||
},
|
||
"g1nation.activeBrainId": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Active brain profile id used for the current chat context."
|
||
},
|
||
"g1nation.secondBrainRepo": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Optional GitHub repository URL used for Second Brain sync."
|
||
},
|
||
"g1nation.autoPushBrain": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "Automatically commit and push Second Brain changes after updates."
|
||
},
|
||
"g1nation.maxContextSize": {
|
||
"type": "number",
|
||
"default": 32000,
|
||
"description": "Maximum character count for active file context. Default: 32000"
|
||
},
|
||
"g1nation.maxAutoSteps": {
|
||
"type": "number",
|
||
"default": 50,
|
||
"description": "Maximum autonomous steps the agent can take per request. Default: 50"
|
||
},
|
||
"g1nation.dryRun": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "If enabled, the agent will ask for approval before committing any file changes."
|
||
},
|
||
"g1nation.telegram.enabled": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "Enable the Telegram bot integration. When on, Astra polls a bot you configure and replies to incoming messages. Off by default — Astra remains 100% local until you opt in."
|
||
},
|
||
"g1nation.telegram.allowedChatIds": {
|
||
"type": "array",
|
||
"default": [],
|
||
"items": { "type": "number" },
|
||
"description": "Optional allowlist of Telegram chat IDs that may message the bot. When empty, every chat that messages the bot is accepted (use with caution)."
|
||
},
|
||
"g1nation.telegram.defaultAgent": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Agent name (matches an entry in the Agent ↔ Knowledge map) used to scope Second Brain retrieval for Telegram replies. Empty falls back to the map's defaultAgent, then to whole-brain search."
|
||
},
|
||
"g1nation.telegram.agentByChatId": {
|
||
"type": "object",
|
||
"default": {},
|
||
"additionalProperties": { "type": "string" },
|
||
"description": "Per-chat override of the Telegram agent. Keys are stringified chat IDs, values are agent names from the knowledge map. Overrides telegram.defaultAgent for the listed chats."
|
||
},
|
||
"g1nation.telegram.contextChunks": {
|
||
"type": "number",
|
||
"default": 6,
|
||
"minimum": 0,
|
||
"maximum": 20,
|
||
"description": "How many Second Brain excerpts to inject into Telegram replies. Set 0 to disable RAG (plain prompt only)."
|
||
},
|
||
"g1nation.skillKnowledgeMapPath": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Absolute path to the agent ↔ knowledge mapping JSON. When empty, defaults to '<workspace>/.astra/agent-knowledge-map.json'."
|
||
},
|
||
"g1nation.skillKnowledgeMap": {
|
||
"type": "object",
|
||
"default": {},
|
||
"description": "Inline fallback for the agent ↔ knowledge mapping. Used only when the JSON file is missing. Shape: { defaultAgent?, agents: [{ name, knowledgeFolders, model?, description? }] }. Folder paths can be absolute, ~-prefixed, or relative to the active brain root."
|
||
},
|
||
"g1nation.agentSkillsPath": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Absolute path to the agent skills folder (`.agent/skills/*.md`). When empty, defaults to '<workspace>/.agent/skills'. Use this on Windows or when your skills live outside the workspace."
|
||
},
|
||
"g1nation.embeddingModel": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Embedding model registered in LM Studio / Ollama (e.g. 'text-embedding-bge-small-en-v1.5', 'nomic-embed-text', 'multilingual-e5-small'). When empty, Astra uses TF-IDF only. When set, the brain is embedded lazily in the background and retrieval blends TF-IDF + cosine similarity for synonym / paraphrase matching. Multilingual models are recommended for Korean content."
|
||
},
|
||
"g1nation.embeddingBlendAlpha": {
|
||
"type": "number",
|
||
"default": 0.5,
|
||
"minimum": 0,
|
||
"maximum": 1,
|
||
"description": "Hybrid score blend: 0 = pure TF-IDF (sparse / keyword), 1 = pure embedding cosine (dense / semantic), 0.5 = balanced. Only used when g1nation.embeddingModel is set. Default 0.5."
|
||
},
|
||
"g1nation.knowledgeMix.secondBrainWeight": {
|
||
"type": "number",
|
||
"default": 50,
|
||
"minimum": 0,
|
||
"maximum": 100,
|
||
"description": "Knowledge Mix (0–100): how heavily the assistant should lean on Second Brain evidence vs. its own general knowledge. 0 = Second Brain disabled (model knowledge only). 50 = balanced (legacy default). 100 = Second Brain is the primary evidence; model knowledge only fills harmless background. Per-agent overrides in the Agent Mapping panel win over this global value."
|
||
},
|
||
"g1nation.enableReflection": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Insert a Self-Reflection (Reflector) stage between Researcher and Writer in the multi-agent workflow. The Reflector critically reviews the plan and research output (gaps, contradictions, unsupported claims, drift from the original objective) and feeds a structured critique to the Writer, which must address it before producing the final report. Reflection failures are non-fatal (the Writer still runs with empty critique). Disable to save one LLM call per mission if you prioritize latency or are running on a very small model."
|
||
},
|
||
"g1nation.autoLessonFromReflection": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Persist substantive Reflector critiques to the active brain as lesson cards under `lessons/auto-reflector/`. Future missions automatically retrieve these cards (via the existing Experience-Memory pipeline) and inject them as ‘[⚠ ACTIVE LESSONS — verify these BEFORE finalizing]’ guardrails into Planner/Researcher/Writer context. A repeated critique (similar title) bumps `occurrences` and escalates `severity` (low→medium→high) instead of duplicating the card, so recurring patterns get louder over time. Disable to keep critiques single-mission only."
|
||
},
|
||
"g1nation.company.intentClassifierModel": {
|
||
"type": "string",
|
||
"default": "",
|
||
"description": "Model used to classify whether an incoming chat message in 1인 기업 모드 is a (a) casual chat / question, (b) follow-up on the previous round, or (c) a brand-new task that should trigger the full work pipeline. Empty → uses g1nation.defaultModel. Pick a fast small model (e.g. gemma 4 e2b) so the classifier doesn't add latency before every chat send. The classifier runs once per user message and returns a one-token-ish JSON verdict, so even slow hardware sees minimal overhead."
|
||
},
|
||
"g1nation.company.disableIntentClassifier": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "Bypass the intent classifier and always run the full work pipeline on every chat message in 1인 기업 모드 (legacy behaviour). Enable this only if you want every input — including 'thanks', 'show me X again' — to dispatch all agents. Off by default because most chat messages aren't new work and shouldn't burn a full pipeline."
|
||
},
|
||
"g1nation.company.autoSelectPipeline": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Let the intent classifier *automatically switch* to the pipeline it recommends for this turn (e.g. short '기획서까지만' for a planning ask, full '풀 프로덕트' for an end-to-end product). Your explicitly-activated pipeline is bypassed for the round but the activation itself isn't changed. On by default — the classifier's read of the user's intent (especially explicit signals like '기획만'·'디자인만') should be honoured. Set to false if you'd rather always run the pipeline you activated yourself."
|
||
},
|
||
"g1nation.company.intentAlignmentMode": {
|
||
"type": "string",
|
||
"enum": ["off", "smart", "strict"],
|
||
"default": "smart",
|
||
"description": "Intent Alignment — turn user prompts into an explicit Requirement Contract (C-G-C-F-Q) before dispatching a pipeline. 'off' = legacy, pipeline runs immediately. 'smart' (default) = run when confidence is high, else show a confirmation card; ask up to N rounds of clarifying questions if information is missing. 'strict' = always show the contract card and require user confirmation, regardless of confidence. Goal: stop agents from silently guessing at the user's mental model."
|
||
},
|
||
"g1nation.company.intentAlignmentMaxRounds": {
|
||
"type": "number",
|
||
"minimum": 1,
|
||
"maximum": 5,
|
||
"default": 3,
|
||
"description": "Maximum back-and-forth rounds the Intent Alignment analyzer is allowed to ask before forcing a 'confirm or cancel' card (it stops asking new questions and shows the current contract for user approval). Each round = one LLM call. Default 3."
|
||
},
|
||
"g1nation.selfReflector.enabled": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Self-Reflector Phase A — append a [Self-Reflector Check] block at the end of every substantive LLM answer (Consistency / Completeness / Accuracy, plus References / Paths for code answers). Zero extra LLM calls — the rule lives in the system prompt and the model self-imposes the checklist. Turns response quality up by making the verification step explicit. Disable for purely casual / chat-only usage."
|
||
},
|
||
"g1nation.selfReflector.externalVerification": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "Self-Reflector Phase B — after every 1인 기업 specialist response, run a *separate* LLM call to verify the output from an outside-context perspective (catches the 'same model self-validates' blind spot). Failed checks trigger one auto-revise round. Off by default — adds +1 LLM call per dispatched stage."
|
||
},
|
||
"g1nation.selfReflector.executionVerification": {
|
||
"type": "boolean",
|
||
"default": false,
|
||
"description": "Self-Reflector Phase C — after a code file is created via <create_file>, automatically run the language's syntax check (Python: py_compile, JS: node --check, TS: project tsc --noEmit). Failures are surfaced in the action report so the user (and the agent on a follow-up) can see exactly what broke. Requires the language toolchain installed on the user's machine. Off by default."
|
||
},
|
||
"g1nation.company.pixelOffice.enabled": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Show the Pixel Office visualisation panel above the chat — a small pixel-office-style display that mirrors the agent's current pipeline status (analyzing, need_clarification, executing, reviewing, waiting_approval, done, etc.) and the current task / contract / open questions. UI layer only; turning it off does not change any agent behaviour."
|
||
},
|
||
"g1nation.company.pixelOffice.bubbles": {
|
||
"type": "boolean",
|
||
"default": true,
|
||
"description": "Show short comic-style speech bubbles above the Pixel Office character on status changes / key events (e.g. '코드 들어간다', '잠깐, 이건 다시 보자', '좋아, 끝났다!'). Bubbles are purely narrative — they never influence the agent's decisions. Disable for a quieter UI."
|
||
},
|
||
"g1nation.google.clientId": {
|
||
"type": "string",
|
||
"default": "",
|
||
"scope": "machine",
|
||
"markdownDescription": "Google OAuth Client ID — `console.cloud.google.com/apis/credentials` → OAuth 2.0 Client ID (Desktop app) 생성 후 복사. **`Astra: Google Calendar OAuth 연결 (쓰기) 🔐`** 명령을 한 번 실행하면 이 값이 자동으로 채워집니다. Calendar + Sheets 둘 다 이 자격증명을 공유.\n\n_scope: machine — Settings Sync 로 다른 기기에 공유되지 않음._"
|
||
},
|
||
"g1nation.google.clientSecret": {
|
||
"type": "string",
|
||
"default": "",
|
||
"scope": "machine",
|
||
"markdownDescription": "Google OAuth Client Secret — Client ID 와 같은 페이지에서 발급. Desktop app OAuth 의 secret 은 Google 가이드상 *진짜 비밀이 아닌 식별자* 지만, settings.json 에 그대로 들어가므로 git 커밋 / 화면 공유 시 주의.\n\n_scope: machine — Settings Sync 안 됨._"
|
||
},
|
||
"g1nation.google.calendarId": {
|
||
"type": "string",
|
||
"default": "primary",
|
||
"markdownDescription": "일정을 등록할 Google Calendar 식별자. 기본 `primary` (본인 메인 캘린더). 특정 캘린더 쓰려면 Calendar 설정 → 캘린더 통합 → 'Calendar ID' 복사 (예: `xxxxxxx@group.calendar.google.com`)."
|
||
},
|
||
"g1nation.google.defaultEventDurationMinutes": {
|
||
"type": "number",
|
||
"default": 60,
|
||
"minimum": 5,
|
||
"maximum": 1440,
|
||
"description": "end / duration 둘 다 없는 일정의 기본 길이 (분). agent 가 회의록에서 시각만 추출하고 종료 시각은 명시 안 했을 때 적용."
|
||
},
|
||
"g1nation.google.icalUrl": {
|
||
"type": "string",
|
||
"default": "",
|
||
"scope": "machine",
|
||
"markdownDescription": "Google Calendar **비공개 iCal URL** — 읽기 전용 모드용. `calendar.google.com/calendar/u/0/r/settings` → 본인 캘린더 → '캘린더 통합' → '비공개 주소(iCal 형식)' 복사. **이 URL 을 가진 사람은 본인 캘린더 모든 일정을 볼 수 있으니 절대 공개 금지.**\n\n_scope: machine — Settings Sync 안 됨. OAuth 와는 별개 — 둘 다 셋업해도 되고 한 쪽만 해도 됨._"
|
||
},
|
||
"g1nation.google.icalDaysAhead": {
|
||
"type": "number",
|
||
"default": 14,
|
||
"minimum": 1,
|
||
"maximum": 90,
|
||
"description": "iCal 캐시에 포함할 다가오는 일정 기간 (일). default 14 = 2주치."
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"scripts": {
|
||
"vscode:prepublish": "npm run test && npm run compile",
|
||
"compile": "esbuild src/extension.ts --bundle --platform=node --external:vscode --outfile=out/extension.js",
|
||
"watch": "tsc -watch -p ./",
|
||
"test": "jest --no-cache --forceExit",
|
||
"test:engine": "jest tests/agentEngine.test.ts --verbose --no-cache",
|
||
"pretest": "npm run compile"
|
||
},
|
||
"devDependencies": {
|
||
"@types/jest": "^29.5.14",
|
||
"@types/node": "18.x",
|
||
"@types/vscode": "^1.80.0",
|
||
"@vercel/ncc": "^0.38.4",
|
||
"esbuild": "^0.28.0",
|
||
"jest": "^29.7.0",
|
||
"ts-jest": "^29.4.9",
|
||
"typescript": "^5.1.3"
|
||
},
|
||
"dependencies": {
|
||
"@lmstudio/sdk": "^1.5.0",
|
||
"pdf-parse": "^2.4.5"
|
||
}
|
||
}
|