agent-issues 0.0.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/agents/agent-issues.agent.md +54 -0
- package/.github/agents/agent-issues.claude.md +51 -0
- package/dist/agent-installer.d.ts +49 -0
- package/dist/agent-installer.js +171 -0
- package/dist/agent-installer.js.map +1 -0
- package/dist/auth-session.d.ts +40 -0
- package/dist/auth-session.js +107 -0
- package/dist/auth-session.js.map +1 -0
- package/dist/body-backfill.d.ts +26 -0
- package/dist/body-backfill.js +219 -0
- package/dist/body-backfill.js.map +1 -0
- package/dist/build-mode.d.ts +1 -0
- package/dist/build-mode.js +1 -0
- package/dist/build-mode.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +61 -0
- package/dist/cli/commands/auth.js +134 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/backfill.d.ts +8 -0
- package/dist/cli/commands/backfill.js +36 -0
- package/dist/cli/commands/backfill.js.map +1 -0
- package/dist/cli/commands/comments.d.ts +34 -0
- package/dist/cli/commands/comments.js +124 -0
- package/dist/cli/commands/comments.js.map +1 -0
- package/dist/cli/commands/context.d.ts +13 -0
- package/dist/cli/commands/context.js +156 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/entities.d.ts +91 -0
- package/dist/cli/commands/entities.js +420 -0
- package/dist/cli/commands/entities.js.map +1 -0
- package/dist/cli/commands/export.d.ts +20 -0
- package/dist/cli/commands/export.js +98 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/fallback.d.ts +6 -0
- package/dist/cli/commands/fallback.js +10 -0
- package/dist/cli/commands/fallback.js.map +1 -0
- package/dist/cli/commands/handoff.d.ts +1 -0
- package/dist/cli/commands/handoff.js +2 -0
- package/dist/cli/commands/handoff.js.map +1 -0
- package/dist/cli/commands/installers.d.ts +37 -0
- package/dist/cli/commands/installers.js +78 -0
- package/dist/cli/commands/installers.js.map +1 -0
- package/dist/cli/commands/kanban.d.ts +8 -0
- package/dist/cli/commands/kanban.js +83 -0
- package/dist/cli/commands/kanban.js.map +1 -0
- package/dist/cli/commands/meta.d.ts +14 -0
- package/dist/cli/commands/meta.js +33 -0
- package/dist/cli/commands/meta.js.map +1 -0
- package/dist/cli/commands/plan-entries.d.ts +30 -0
- package/dist/cli/commands/plan-entries.js +94 -0
- package/dist/cli/commands/plan-entries.js.map +1 -0
- package/dist/cli/commands/site.d.ts +29 -0
- package/dist/cli/commands/site.js +89 -0
- package/dist/cli/commands/site.js.map +1 -0
- package/dist/cli/commands/sql.d.ts +6 -0
- package/dist/cli/commands/sql.js +21 -0
- package/dist/cli/commands/sql.js.map +1 -0
- package/dist/cli/commands/synchronize.d.ts +12 -0
- package/dist/cli/commands/synchronize.js +31 -0
- package/dist/cli/commands/synchronize.js.map +1 -0
- package/dist/cli/commands/tenants.d.ts +29 -0
- package/dist/cli/commands/tenants.js +101 -0
- package/dist/cli/commands/tenants.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +120 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/renderers.d.ts +250 -0
- package/dist/cli/renderers.js +286 -0
- package/dist/cli/renderers.js.map +1 -0
- package/dist/cli/shared.d.ts +97 -0
- package/dist/cli/shared.js +192 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +41 -0
- package/dist/cli.js.map +1 -0
- package/dist/context-cli.d.ts +16 -0
- package/dist/context-cli.js +131 -0
- package/dist/context-cli.js.map +1 -0
- package/dist/daemon/daemon-lifecycle.d.ts +1 -0
- package/dist/daemon/daemon-lifecycle.js +2 -0
- package/dist/daemon/daemon-lifecycle.js.map +1 -0
- package/dist/daemon/daemon-main.d.ts +14 -0
- package/dist/daemon/daemon-main.js +30 -0
- package/dist/daemon/daemon-main.js.map +1 -0
- package/dist/daemon/local-daemon-store.d.ts +21 -0
- package/dist/daemon/local-daemon-store.js +31 -0
- package/dist/daemon/local-daemon-store.js.map +1 -0
- package/dist/entity-projection.d.ts +141 -0
- package/dist/entity-projection.js +147 -0
- package/dist/entity-projection.js.map +1 -0
- package/dist/entra-device-login.d.ts +12 -0
- package/dist/entra-device-login.js +40 -0
- package/dist/entra-device-login.js.map +1 -0
- package/dist/export-files.d.ts +24 -0
- package/dist/export-files.js +230 -0
- package/dist/export-files.js.map +1 -0
- package/dist/export-markdown.d.ts +24 -0
- package/dist/export-markdown.js +343 -0
- package/dist/export-markdown.js.map +1 -0
- package/dist/help.d.ts +112 -0
- package/dist/help.js +1430 -0
- package/dist/help.js.map +1 -0
- package/dist/kanban/assets.d.ts +3 -0
- package/dist/kanban/assets.js +37 -0
- package/dist/kanban/assets.js.map +1 -0
- package/dist/kanban/index.d.ts +1 -0
- package/dist/kanban/index.js +2 -0
- package/dist/kanban/index.js.map +1 -0
- package/dist/kanban/server.d.ts +28 -0
- package/dist/kanban/server.js +118 -0
- package/dist/kanban/server.js.map +1 -0
- package/dist/mcp-installer.d.ts +32 -0
- package/dist/mcp-installer.js +118 -0
- package/dist/mcp-installer.js.map +1 -0
- package/dist/mcp-server/index.d.ts +11 -0
- package/dist/mcp-server/index.js +504 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/mcp-server/index.test.d.ts +1 -0
- package/dist/mcp-server/index.test.js +746 -0
- package/dist/mcp-server/index.test.js.map +1 -0
- package/dist/mcp-server/mcp-tool-audit.d.ts +6 -0
- package/dist/mcp-server/mcp-tool-audit.js +47 -0
- package/dist/mcp-server/mcp-tool-audit.js.map +1 -0
- package/dist/mcp-server/stdio.d.ts +2 -0
- package/dist/mcp-server/stdio.js +7 -0
- package/dist/mcp-server/stdio.js.map +1 -0
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +19 -0
- package/dist/mcp.js.map +1 -0
- package/dist/open-storage-driver.d.ts +53 -0
- package/dist/open-storage-driver.js +71 -0
- package/dist/open-storage-driver.js.map +1 -0
- package/dist/open-synchronize-stores.d.ts +24 -0
- package/dist/open-synchronize-stores.js +34 -0
- package/dist/open-synchronize-stores.js.map +1 -0
- package/dist/project-identity.d.ts +23 -0
- package/dist/project-identity.js +121 -0
- package/dist/project-identity.js.map +1 -0
- package/dist/runtime-access-boundary.d.ts +7 -0
- package/dist/runtime-access-boundary.js +182 -0
- package/dist/runtime-access-boundary.js.map +1 -0
- package/dist/service-discovery.d.ts +10 -0
- package/dist/service-discovery.js +64 -0
- package/dist/service-discovery.js.map +1 -0
- package/dist/site/assets.d.ts +4 -0
- package/dist/site/assets.js +46 -0
- package/dist/site/assets.js.map +1 -0
- package/dist/site/cloud-events-relay.d.ts +18 -0
- package/dist/site/cloud-events-relay.js +78 -0
- package/dist/site/cloud-events-relay.js.map +1 -0
- package/dist/site/index.d.ts +1 -0
- package/dist/site/index.js +2 -0
- package/dist/site/index.js.map +1 -0
- package/dist/site/server.d.ts +42 -0
- package/dist/site/server.js +320 -0
- package/dist/site/server.js.map +1 -0
- package/dist/skill-installer.d.ts +35 -0
- package/dist/skill-installer.js +174 -0
- package/dist/skill-installer.js.map +1 -0
- package/dist/vitest-setup.d.ts +1 -0
- package/dist/vitest-setup.js +7 -0
- package/dist/vitest-setup.js.map +1 -0
- package/package.json +42 -0
- package/site/dist/assets/index-DKEVC0aQ.css +1 -0
- package/site/dist/assets/index-DSR4mIml.js +4396 -0
- package/site/dist/index.html +14 -0
- package/skills/agent-issues-language.md +5 -0
- package/skills/agent-issues-operating-contract.md +208 -0
- package/skills/ai-agent-issues/SKILL.md +127 -0
- package/skills/ai-domain-modeling/ADR-FORMAT.md +48 -0
- package/skills/ai-domain-modeling/CONTEXT-FORMAT.md +54 -0
- package/skills/ai-domain-modeling/SKILL.md +45 -0
- package/skills/ai-grill-with-docs/SKILL.md +28 -0
- package/skills/ai-handoff/SKILL.md +41 -0
- package/skills/ai-implement/SKILL.md +98 -0
- package/skills/ai-migrate-docs/SKILL.md +65 -0
- package/skills/ai-next-work/SKILL.md +43 -0
- package/skills/ai-plan/SKILL.md +41 -0
- package/skills/ai-prepare/SKILL.md +79 -0
- package/skills/ai-prototype/LOGIC.md +67 -0
- package/skills/ai-prototype/SKILL.md +31 -0
- package/skills/ai-prototype/UI.md +112 -0
- package/skills/ai-recipe-migration/SKILL.md +49 -0
- package/skills/ai-start-work/SKILL.md +56 -0
- package/skills/ai-tdd/SKILL.md +99 -0
- package/skills/ai-tdd/deep-modules.md +33 -0
- package/skills/ai-tdd/interface-design.md +20 -0
- package/skills/ai-tdd/mocking.md +28 -0
- package/skills/ai-tdd/refactoring.md +10 -0
- package/skills/ai-tdd/tests.md +74 -0
- package/skills/ai-to-issues/SKILL.md +70 -0
- package/skills/ai-to-prd/SKILL.md +33 -0
- package/skills/ai-wayfinder/SKILL.md +110 -0
- package/skills/recipes/README.md +29 -0
- package/skills/recipes/adr.md +21 -0
- package/skills/recipes/context-summary.md +17 -0
- package/skills/recipes/context-term.md +3 -0
- package/skills/recipes/debt.md +21 -0
- package/skills/recipes/epic.md +21 -0
- package/skills/recipes/handoff.md +29 -0
- package/skills/recipes/initiative.md +21 -0
- package/skills/recipes/issue-comment.md +15 -0
- package/skills/recipes/issue.md +33 -0
- package/skills/recipes/prd.md +29 -0
- package/skills/recipes/project.md +21 -0
- package/skills/recipes/user-story.md +15 -0
- package/skills/recipes/version.md +13 -0
- package/skills/recipes/wayfinder-map.md +25 -0
- package/skills/recipes/wayfinder-ticket.md +17 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Agent Issues
|
|
3
|
+
description: "Use when working from an agent-issues issue, an ISS id, or an issue-guided implementation task. This agent starts by loading issue context with agent-issues, keeps changes scoped to that record, and validates the touched slice before expanding."
|
|
4
|
+
tools: [vscode/extensions, vscode/askQuestions, vscode/installExtension, vscode/newWorkspace, vscode/runCommand, vscode/vscodeAPI, vscode/toolSearch, execute, read, agent, browser, vscodeGeneral/rename, vscodeGeneral/usages, vscodeGeneral/toolSearch, vscodeNotebooks/createJupyterNotebook, vscodeNotebooks/editNotebook, edit, search, web, 'agent-issues/*', todo]
|
|
5
|
+
argument-hint: "Issue-first task, e.g. ISS53 implement context search badge"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are the issue-first implementation agent for this workspace.
|
|
10
|
+
|
|
11
|
+
Your job is to keep work anchored to the active `agent-issues` record instead of drifting into broad repo exploration or unaudited implementation.
|
|
12
|
+
|
|
13
|
+
Follow the shared [language standard](./agent-issues-language.md).
|
|
14
|
+
|
|
15
|
+
## When To Use This Agent
|
|
16
|
+
|
|
17
|
+
- The prompt includes an `ISS` id such as `ISS53`
|
|
18
|
+
- The user wants work driven by `agent-issues`
|
|
19
|
+
- The user wants stricter adherence to the issue context than the default agent provides
|
|
20
|
+
|
|
21
|
+
## Required Workflow
|
|
22
|
+
|
|
23
|
+
1. If the user prompt includes an `ISS` id, first use the `agent-issues` MCP tools to load `entity_show`, `relation_query`, and `context_show` for that issue.
|
|
24
|
+
Use the CLI only when the MCP server is unavailable or lacks the required operation.
|
|
25
|
+
2. Read that issue context before proposing or making code changes.
|
|
26
|
+
3. Keep the plan and edits scoped to the issue's stated outcome, dependencies, and terminology.
|
|
27
|
+
4. Before the first edit, identify one local hypothesis and one cheap discriminating check.
|
|
28
|
+
5. After the first substantive edit, run the narrowest available validation for the touched slice before widening scope.
|
|
29
|
+
6. After the implementation and its focused validation are complete, launch one independent read-only review subagent covering behavior and contract coverage plus code and regression risks. Fix valid material findings and rerun focused validation before marking the issue done.
|
|
30
|
+
|
|
31
|
+
## Constraints
|
|
32
|
+
|
|
33
|
+
- Do not start with broad repo mapping when issue context is available.
|
|
34
|
+
- Do not make behavior changes outside the active issue without calling that out explicitly.
|
|
35
|
+
- Do not invent missing issue context. If the issue record is insufficient, say what is missing and ask only for the minimum clarification.
|
|
36
|
+
- Do not stop at planning when the task is implementable from the loaded issue context.
|
|
37
|
+
- Prefer the project's existing scripts, tests, and conventions over ad hoc commands.
|
|
38
|
+
- Do not preserve obsolete code, features, compatibility paths, or public APIs solely because an old test expects them. When current issue scope or a relevant ADR replaces behavior, remove the old implementation and update or remove the tests that specify it.
|
|
39
|
+
- If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code.
|
|
40
|
+
|
|
41
|
+
## Execution Rules
|
|
42
|
+
|
|
43
|
+
- Treat the issue text, relations, and context as the primary source of truth for scope.
|
|
44
|
+
- Use the same domain terms as the issue and linked context in plans and summaries.
|
|
45
|
+
- If the user does not provide an `ISS` id, you may proceed normally, but still prefer a narrow, validation-first workflow.
|
|
46
|
+
- If the issue points to a neighboring document, test, or owning implementation surface, go there before exploring elsewhere.
|
|
47
|
+
|
|
48
|
+
## Output
|
|
49
|
+
|
|
50
|
+
Return concise progress updates tied to the issue, then finish with:
|
|
51
|
+
|
|
52
|
+
- what changed
|
|
53
|
+
- what validation ran
|
|
54
|
+
- any remaining gap between the current code and the issue scope
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-issues
|
|
3
|
+
description: "Use when working from an agent-issues issue, an ISS id, or an issue-guided implementation task. This agent starts by loading issue context with agent-issues, keeps changes scoped to that record, and validates the touched slice before expanding."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are the issue-first implementation agent for this workspace.
|
|
7
|
+
|
|
8
|
+
Your job is to keep work anchored to the active `agent-issues` record instead of drifting into broad repo exploration or unaudited implementation.
|
|
9
|
+
|
|
10
|
+
Follow the shared [language standard](./agent-issues-language.md).
|
|
11
|
+
|
|
12
|
+
## When To Use This Agent
|
|
13
|
+
|
|
14
|
+
- The prompt includes an `ISS` id such as `ISS53`
|
|
15
|
+
- The user wants work driven by `agent-issues`
|
|
16
|
+
- The user wants stricter adherence to the issue context than the default agent provides
|
|
17
|
+
|
|
18
|
+
## Required Workflow
|
|
19
|
+
|
|
20
|
+
1. If the user prompt includes an `ISS` id, first use the `agent-issues` MCP tools to load `entity_show`, `relation_query`, and `context_show` for that issue.
|
|
21
|
+
Use the CLI only when the MCP server is unavailable or lacks the required operation.
|
|
22
|
+
2. Read that issue context before proposing or making code changes.
|
|
23
|
+
3. Keep the plan and edits scoped to the issue's stated outcome, dependencies, and terminology.
|
|
24
|
+
4. Before the first edit, identify one local hypothesis and one cheap discriminating check.
|
|
25
|
+
5. After the first substantive edit, run the narrowest available validation for the touched slice before widening scope.
|
|
26
|
+
6. After implementation and focused validation, launch one independent read-only review covering behavior, contract coverage, code, and regression risks. Fix valid material findings and rerun focused validation before marking the issue done.
|
|
27
|
+
|
|
28
|
+
## Constraints
|
|
29
|
+
|
|
30
|
+
- Do not start with broad repo mapping when issue context is available.
|
|
31
|
+
- Do not make behavior changes outside the active issue without calling that out explicitly.
|
|
32
|
+
- Do not invent missing issue context. If the issue record is insufficient, say what is missing and ask only for the minimum clarification.
|
|
33
|
+
- Do not stop at planning when the task is implementable from the loaded issue context.
|
|
34
|
+
- Prefer the project's existing scripts and tests over ad hoc commands.
|
|
35
|
+
- Do not preserve obsolete code, features, compatibility paths, or public APIs solely because an old test expects them. When current issue scope or a relevant ADR replaces behavior, remove the old implementation and update or remove the tests that specify it.
|
|
36
|
+
- If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong. Fix the code.
|
|
37
|
+
|
|
38
|
+
## Execution Rules
|
|
39
|
+
|
|
40
|
+
- Treat the issue text, relations, and context as the primary source of truth for scope.
|
|
41
|
+
- Use the same domain terms as the issue and linked context in plans and summaries.
|
|
42
|
+
- If the user does not provide an `ISS` id, you may proceed normally, but still prefer a narrow, validation-first workflow.
|
|
43
|
+
- If the issue points to a neighboring document, test, or owning implementation surface, go there before exploring elsewhere.
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
Return concise progress updates tied to the issue, then finish with:
|
|
48
|
+
|
|
49
|
+
- what changed
|
|
50
|
+
- what validation ran
|
|
51
|
+
- any remaining gap between the current code and the issue scope
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
type AgentHost = "claude" | "copilot" | "vscode";
|
|
2
|
+
type AgentInstallRecord = {
|
|
3
|
+
installedName: string;
|
|
4
|
+
agentFile: string;
|
|
5
|
+
};
|
|
6
|
+
type AgentInstallation = AgentInstallRecord & {
|
|
7
|
+
host: AgentHost;
|
|
8
|
+
targetDir: string;
|
|
9
|
+
};
|
|
10
|
+
export type InstallAgentResult = {
|
|
11
|
+
targetDir: string;
|
|
12
|
+
installed: AgentInstallRecord & {
|
|
13
|
+
status: "installed" | "updated" | "skipped";
|
|
14
|
+
};
|
|
15
|
+
additionalInstalled: Array<AgentInstallation & {
|
|
16
|
+
status: "installed" | "updated" | "skipped";
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export type UninstallAgentResult = {
|
|
20
|
+
targetDir: string;
|
|
21
|
+
removed: AgentInstallRecord & {
|
|
22
|
+
status: "removed" | "missing";
|
|
23
|
+
};
|
|
24
|
+
additionalRemoved: Array<AgentInstallation & {
|
|
25
|
+
status: "removed" | "missing";
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
export type ListAgentResult = {
|
|
29
|
+
targetDir: string;
|
|
30
|
+
agent: AgentInstallRecord & {
|
|
31
|
+
status: "installed" | "partial" | "missing";
|
|
32
|
+
};
|
|
33
|
+
additionalAgents: Array<AgentInstallation & {
|
|
34
|
+
status: "installed" | "partial" | "missing";
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
export declare function getDefaultAgentInstallDir(): string;
|
|
38
|
+
export declare function getDefaultAgentInstallDirs(): Record<AgentHost, string>;
|
|
39
|
+
export declare function installAgent(input: {
|
|
40
|
+
targetDir?: string;
|
|
41
|
+
force?: boolean;
|
|
42
|
+
}): InstallAgentResult;
|
|
43
|
+
export declare function uninstallAgent(input: {
|
|
44
|
+
targetDir?: string;
|
|
45
|
+
}): UninstallAgentResult;
|
|
46
|
+
export declare function listAgent(input: {
|
|
47
|
+
targetDir?: string;
|
|
48
|
+
}): ListAgentResult;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const AGENT_FILE_NAME = "agent-issues.agent.md";
|
|
6
|
+
const CLAUDE_AGENT_FILE_NAME = "agent-issues.md";
|
|
7
|
+
const LEGACY_HOOK_FILE_NAME = "agent-issues-enforcer.mjs";
|
|
8
|
+
const LANGUAGE_FILE_NAME = "agent-issues-language.md";
|
|
9
|
+
const RECIPES_DIRECTORY_NAME = "recipes";
|
|
10
|
+
const AGENT_FILES_MANIFEST = ".agent-issues-agent-files.json";
|
|
11
|
+
const INSTALLED_AGENT_NAME = "agent-issues";
|
|
12
|
+
function getVsCodeUserDir() {
|
|
13
|
+
if (process.platform === "win32") {
|
|
14
|
+
const appData = process.env.APPDATA ?? path.join(homedir(), "AppData", "Roaming");
|
|
15
|
+
return path.join(appData, "Code", "User");
|
|
16
|
+
}
|
|
17
|
+
if (process.platform === "darwin")
|
|
18
|
+
return path.join(homedir(), "Library", "Application Support", "Code", "User");
|
|
19
|
+
const configHome = process.env.XDG_CONFIG_HOME ?? path.join(homedir(), ".config");
|
|
20
|
+
return path.join(configHome, "Code", "User");
|
|
21
|
+
}
|
|
22
|
+
export function getDefaultAgentInstallDir() {
|
|
23
|
+
return getDefaultAgentInstallDirs().vscode;
|
|
24
|
+
}
|
|
25
|
+
export function getDefaultAgentInstallDirs() {
|
|
26
|
+
return {
|
|
27
|
+
claude: path.join(homedir(), ".claude", "agents"),
|
|
28
|
+
copilot: path.join(homedir(), ".copilot", "agents"),
|
|
29
|
+
vscode: path.join(getVsCodeUserDir(), "prompts")
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function installAgent(input) {
|
|
33
|
+
const sourceRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", ".github");
|
|
34
|
+
const [primaryTarget, ...additionalTargets] = getAgentTargets(input.targetDir);
|
|
35
|
+
const installed = installAgentAtTarget(primaryTarget, sourceRoot, Boolean(input.force));
|
|
36
|
+
const additionalInstalled = additionalTargets.map((target) => ({
|
|
37
|
+
...installAgentAtTarget(target, sourceRoot, Boolean(input.force)),
|
|
38
|
+
host: target.host,
|
|
39
|
+
targetDir: target.targetDir
|
|
40
|
+
}));
|
|
41
|
+
return {
|
|
42
|
+
targetDir: primaryTarget.targetDir,
|
|
43
|
+
installed,
|
|
44
|
+
additionalInstalled
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function uninstallAgent(input) {
|
|
48
|
+
const [primaryTarget, ...additionalTargets] = getAgentTargets(input.targetDir);
|
|
49
|
+
const removed = uninstallAgentAtTarget(primaryTarget);
|
|
50
|
+
const additionalRemoved = additionalTargets.map((target) => ({
|
|
51
|
+
...uninstallAgentAtTarget(target),
|
|
52
|
+
host: target.host,
|
|
53
|
+
targetDir: target.targetDir
|
|
54
|
+
}));
|
|
55
|
+
return {
|
|
56
|
+
targetDir: primaryTarget.targetDir,
|
|
57
|
+
removed,
|
|
58
|
+
additionalRemoved
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function listAgent(input) {
|
|
62
|
+
const [primaryTarget, ...additionalTargets] = getAgentTargets(input.targetDir);
|
|
63
|
+
const agent = listAgentAtTarget(primaryTarget);
|
|
64
|
+
const additionalAgents = additionalTargets.map((target) => ({
|
|
65
|
+
...listAgentAtTarget(target),
|
|
66
|
+
host: target.host,
|
|
67
|
+
targetDir: target.targetDir
|
|
68
|
+
}));
|
|
69
|
+
return {
|
|
70
|
+
targetDir: primaryTarget.targetDir,
|
|
71
|
+
agent,
|
|
72
|
+
additionalAgents
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function getAgentTargets(targetDir) {
|
|
76
|
+
if (targetDir) {
|
|
77
|
+
return [{ host: "vscode", targetDir: path.resolve(targetDir), agentFileName: AGENT_FILE_NAME }];
|
|
78
|
+
}
|
|
79
|
+
const targetDirs = getDefaultAgentInstallDirs();
|
|
80
|
+
return [
|
|
81
|
+
{ host: "vscode", targetDir: targetDirs.vscode, agentFileName: AGENT_FILE_NAME },
|
|
82
|
+
{ host: "copilot", targetDir: targetDirs.copilot, agentFileName: AGENT_FILE_NAME },
|
|
83
|
+
{ host: "claude", targetDir: targetDirs.claude, agentFileName: CLAUDE_AGENT_FILE_NAME }
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
function installAgentAtTarget(target, sourceRoot, force) {
|
|
87
|
+
const sourceAgentFile = path.join(sourceRoot, "agents", target.host === "claude" ? "agent-issues.claude.md" : AGENT_FILE_NAME);
|
|
88
|
+
const sourceLanguageFile = path.join(sourceRoot, "..", "skills", LANGUAGE_FILE_NAME);
|
|
89
|
+
const sourceRecipesDirectory = path.join(sourceRoot, "..", "skills", RECIPES_DIRECTORY_NAME);
|
|
90
|
+
const destinationAgentFile = path.join(target.targetDir, target.agentFileName);
|
|
91
|
+
const legacyHookFile = path.join(target.targetDir, LEGACY_HOOK_FILE_NAME);
|
|
92
|
+
const destinationLanguageFile = path.join(target.targetDir, LANGUAGE_FILE_NAME);
|
|
93
|
+
const destinationRecipesDirectory = path.join(target.targetDir, RECIPES_DIRECTORY_NAME);
|
|
94
|
+
const existed = existsSync(destinationAgentFile);
|
|
95
|
+
if (!existsSync(sourceAgentFile) || !existsSync(sourceLanguageFile) || !existsSync(sourceRecipesDirectory)) {
|
|
96
|
+
throw new Error(`Packaged agent assets not found under ${sourceRoot}`);
|
|
97
|
+
}
|
|
98
|
+
mkdirSync(target.targetDir, { recursive: true });
|
|
99
|
+
if (existed && !force) {
|
|
100
|
+
return {
|
|
101
|
+
installedName: INSTALLED_AGENT_NAME,
|
|
102
|
+
agentFile: destinationAgentFile,
|
|
103
|
+
status: "skipped"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
cpSync(sourceAgentFile, destinationAgentFile);
|
|
107
|
+
rmSync(legacyHookFile, { force: true });
|
|
108
|
+
cpSync(sourceLanguageFile, destinationLanguageFile);
|
|
109
|
+
if (force || !existsSync(destinationRecipesDirectory)) {
|
|
110
|
+
if (existsSync(destinationRecipesDirectory)) {
|
|
111
|
+
rmSync(destinationRecipesDirectory, { force: true, recursive: true });
|
|
112
|
+
}
|
|
113
|
+
cpSync(sourceRecipesDirectory, destinationRecipesDirectory, { recursive: true });
|
|
114
|
+
writeOwnedRecipeCatalog(target.targetDir);
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
installedName: INSTALLED_AGENT_NAME,
|
|
118
|
+
agentFile: destinationAgentFile,
|
|
119
|
+
status: existed ? "updated" : "installed"
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function uninstallAgentAtTarget(target) {
|
|
123
|
+
const destinationAgentFile = path.join(target.targetDir, target.agentFileName);
|
|
124
|
+
const legacyHookFile = path.join(target.targetDir, LEGACY_HOOK_FILE_NAME);
|
|
125
|
+
const destinationLanguageFile = path.join(target.targetDir, LANGUAGE_FILE_NAME);
|
|
126
|
+
const destinationRecipesDirectory = path.join(target.targetDir, RECIPES_DIRECTORY_NAME);
|
|
127
|
+
const existed = existsSync(destinationAgentFile);
|
|
128
|
+
for (const destinationFile of [destinationAgentFile, legacyHookFile, destinationLanguageFile]) {
|
|
129
|
+
if (existsSync(destinationFile)) {
|
|
130
|
+
rmSync(destinationFile, { force: true });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (hasOwnedRecipeCatalog(target.targetDir) && existsSync(destinationRecipesDirectory)) {
|
|
134
|
+
rmSync(destinationRecipesDirectory, { force: true, recursive: true });
|
|
135
|
+
}
|
|
136
|
+
rmSync(path.join(target.targetDir, AGENT_FILES_MANIFEST), { force: true });
|
|
137
|
+
return {
|
|
138
|
+
installedName: INSTALLED_AGENT_NAME,
|
|
139
|
+
agentFile: destinationAgentFile,
|
|
140
|
+
status: existed ? "removed" : "missing"
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function listAgentAtTarget(target) {
|
|
144
|
+
const destinationAgentFile = path.join(target.targetDir, target.agentFileName);
|
|
145
|
+
const destinationRecipesDirectory = path.join(target.targetDir, RECIPES_DIRECTORY_NAME);
|
|
146
|
+
const agentExists = existsSync(destinationAgentFile);
|
|
147
|
+
const recipesExist = existsSync(destinationRecipesDirectory);
|
|
148
|
+
const ownsRecipeCatalog = hasOwnedRecipeCatalog(target.targetDir);
|
|
149
|
+
return {
|
|
150
|
+
installedName: INSTALLED_AGENT_NAME,
|
|
151
|
+
agentFile: destinationAgentFile,
|
|
152
|
+
status: agentExists && recipesExist && ownsRecipeCatalog ? "installed" : agentExists || recipesExist ? "partial" : "missing"
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function hasOwnedRecipeCatalog(targetDir) {
|
|
156
|
+
const manifestPath = path.join(targetDir, AGENT_FILES_MANIFEST);
|
|
157
|
+
if (!existsSync(manifestPath)) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
162
|
+
return parsed.recipeCatalog === true;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function writeOwnedRecipeCatalog(targetDir) {
|
|
169
|
+
writeFileSync(path.join(targetDir, AGENT_FILES_MANIFEST), `${JSON.stringify({ recipeCatalog: true }, null, "\t")}\n`);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=agent-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-installer.js","sourceRoot":"","sources":["../src/agent-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type OsCredentialStoreOptions } from "@agent-issues/core";
|
|
2
|
+
export type LocalSavedLogin = {
|
|
3
|
+
name: "local";
|
|
4
|
+
kind: "local";
|
|
5
|
+
};
|
|
6
|
+
export type RemoteSavedLogin = {
|
|
7
|
+
name: string;
|
|
8
|
+
kind: "remote";
|
|
9
|
+
serviceUrl: string;
|
|
10
|
+
tenantId: string;
|
|
11
|
+
userId: string;
|
|
12
|
+
displayName?: string;
|
|
13
|
+
accessToken: string;
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
};
|
|
16
|
+
export type SavedLogin = LocalSavedLogin | RemoteSavedLogin;
|
|
17
|
+
export type SavedLoginView = LocalSavedLogin | Omit<RemoteSavedLogin, "accessToken">;
|
|
18
|
+
/** Strips remote credentials so callers can safely display or log a saved login. */
|
|
19
|
+
export declare function toSavedLoginView(login: LocalSavedLogin): LocalSavedLogin;
|
|
20
|
+
export declare function toSavedLoginView(login: RemoteSavedLogin): Omit<RemoteSavedLogin, "accessToken">;
|
|
21
|
+
export declare function toSavedLoginView(login: SavedLogin): SavedLoginView;
|
|
22
|
+
export type SavedLoginStoreOptions = OsCredentialStoreOptions & {
|
|
23
|
+
/**
|
|
24
|
+
* Overrides the directory checked for legacy plaintext routing files to
|
|
25
|
+
* remove during upgrade. Production defaults to
|
|
26
|
+
* `resolveAgentIssuesHomeDirectory()` (`~/.agent-issues`); tests inject a
|
|
27
|
+
* temp directory so no real user state is touched.
|
|
28
|
+
*/
|
|
29
|
+
homeDirectory?: string;
|
|
30
|
+
};
|
|
31
|
+
/** Returns every saved login in switching order, beginning with local. */
|
|
32
|
+
export declare function listSavedLogins(_options?: SavedLoginStoreOptions): Promise<SavedLogin[]>;
|
|
33
|
+
/** Returns the one globally active saved login. */
|
|
34
|
+
export declare function getActiveSavedLogin(options?: SavedLoginStoreOptions): Promise<SavedLogin>;
|
|
35
|
+
/** Creates or refreshes a named remote login and makes it active. */
|
|
36
|
+
export declare function saveSavedLogin(login: RemoteSavedLogin, options?: SavedLoginStoreOptions): Promise<void>;
|
|
37
|
+
/** Persists the globally active name when it identifies an existing saved login. */
|
|
38
|
+
export declare function setActiveSavedLogin(name: string, options?: SavedLoginStoreOptions): Promise<void>;
|
|
39
|
+
/** Removes a remote saved login, falling back to local when it was active. */
|
|
40
|
+
export declare function removeSavedLogin(name: string, options?: SavedLoginStoreOptions): Promise<void>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getCredential, resolveAgentIssuesHomeDirectory, setCredential } from "@agent-issues/core";
|
|
4
|
+
const LOCAL_SAVED_LOGIN = { name: "local", kind: "local" };
|
|
5
|
+
export function toSavedLoginView(login) {
|
|
6
|
+
if (login.kind === "local")
|
|
7
|
+
return login;
|
|
8
|
+
const { accessToken: _accessToken, ...view } = login;
|
|
9
|
+
return view;
|
|
10
|
+
}
|
|
11
|
+
const SERVICE = "agent-issues-auth";
|
|
12
|
+
const ACCOUNT = "sessions";
|
|
13
|
+
const LEGACY_AUTH_SESSION_FILENAME = "auth.json";
|
|
14
|
+
const LEGACY_CLOUD_BINDINGS_FILENAME = "cloud-bindings.json";
|
|
15
|
+
const SAVED_LOGIN_CREDENTIAL_VERSION = 1;
|
|
16
|
+
function resolveLegacyFilePath(filename, options) {
|
|
17
|
+
const homeDirectory = options?.homeDirectory ?? resolveAgentIssuesHomeDirectory();
|
|
18
|
+
return path.join(homeDirectory, filename);
|
|
19
|
+
}
|
|
20
|
+
function createLocalSavedLoginCredential() {
|
|
21
|
+
return { version: SAVED_LOGIN_CREDENTIAL_VERSION, activeName: LOCAL_SAVED_LOGIN.name, remoteLogins: [] };
|
|
22
|
+
}
|
|
23
|
+
function parseSavedLoginCredential(raw) {
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(raw);
|
|
26
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
27
|
+
return undefined;
|
|
28
|
+
const { version, activeName, remoteLogins } = parsed;
|
|
29
|
+
if (version !== SAVED_LOGIN_CREDENTIAL_VERSION || typeof activeName !== "string" || !Array.isArray(remoteLogins)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
version,
|
|
34
|
+
activeName,
|
|
35
|
+
remoteLogins
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function readSavedLoginCredential(options) {
|
|
43
|
+
rmSync(resolveLegacyFilePath(LEGACY_AUTH_SESSION_FILENAME, options), { force: true });
|
|
44
|
+
rmSync(resolveLegacyFilePath(LEGACY_CLOUD_BINDINGS_FILENAME, options), { force: true });
|
|
45
|
+
const stored = await getCredential(SERVICE, ACCOUNT, options);
|
|
46
|
+
if (stored !== undefined) {
|
|
47
|
+
const current = parseSavedLoginCredential(stored);
|
|
48
|
+
if (current)
|
|
49
|
+
return current;
|
|
50
|
+
}
|
|
51
|
+
const migrated = createLocalSavedLoginCredential();
|
|
52
|
+
await setCredential(SERVICE, ACCOUNT, JSON.stringify(migrated), options);
|
|
53
|
+
return migrated;
|
|
54
|
+
}
|
|
55
|
+
async function writeSavedLoginCredential(file, options) {
|
|
56
|
+
await setCredential(SERVICE, ACCOUNT, JSON.stringify(file), options);
|
|
57
|
+
}
|
|
58
|
+
/** Returns every saved login in switching order, beginning with local. */
|
|
59
|
+
export async function listSavedLogins(_options) {
|
|
60
|
+
return [LOCAL_SAVED_LOGIN, ...(await readSavedLoginCredential(_options)).remoteLogins];
|
|
61
|
+
}
|
|
62
|
+
/** Returns the one globally active saved login. */
|
|
63
|
+
export async function getActiveSavedLogin(options) {
|
|
64
|
+
const file = await readSavedLoginCredential(options);
|
|
65
|
+
return file.remoteLogins.find(({ name }) => name === file.activeName) ?? LOCAL_SAVED_LOGIN;
|
|
66
|
+
}
|
|
67
|
+
/** Creates or refreshes a named remote login and makes it active. */
|
|
68
|
+
export async function saveSavedLogin(login, options) {
|
|
69
|
+
if (login.name === LOCAL_SAVED_LOGIN.name) {
|
|
70
|
+
throw new Error('Saved-login name "local" is reserved.');
|
|
71
|
+
}
|
|
72
|
+
const file = await readSavedLoginCredential(options);
|
|
73
|
+
const existingIndex = file.remoteLogins.findIndex(({ name }) => name === login.name);
|
|
74
|
+
if (existingIndex === -1) {
|
|
75
|
+
file.remoteLogins.push(login);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
file.remoteLogins[existingIndex] = login;
|
|
79
|
+
}
|
|
80
|
+
file.activeName = login.name;
|
|
81
|
+
await writeSavedLoginCredential(file, options);
|
|
82
|
+
}
|
|
83
|
+
/** Persists the globally active name when it identifies an existing saved login. */
|
|
84
|
+
export async function setActiveSavedLogin(name, options) {
|
|
85
|
+
const file = await readSavedLoginCredential(options);
|
|
86
|
+
if (name !== LOCAL_SAVED_LOGIN.name && !file.remoteLogins.some((login) => login.name === name)) {
|
|
87
|
+
throw new Error(`No saved login named "${name}".`);
|
|
88
|
+
}
|
|
89
|
+
file.activeName = name;
|
|
90
|
+
await writeSavedLoginCredential(file, options);
|
|
91
|
+
}
|
|
92
|
+
/** Removes a remote saved login, falling back to local when it was active. */
|
|
93
|
+
export async function removeSavedLogin(name, options) {
|
|
94
|
+
if (name === LOCAL_SAVED_LOGIN.name) {
|
|
95
|
+
throw new Error('The local saved login cannot be removed.');
|
|
96
|
+
}
|
|
97
|
+
const file = await readSavedLoginCredential(options);
|
|
98
|
+
if (!file.remoteLogins.some((login) => login.name === name)) {
|
|
99
|
+
throw new Error(`No saved login named "${name}".`);
|
|
100
|
+
}
|
|
101
|
+
file.remoteLogins = file.remoteLogins.filter((login) => login.name !== name);
|
|
102
|
+
if (file.activeName === name) {
|
|
103
|
+
file.activeName = LOCAL_SAVED_LOGIN.name;
|
|
104
|
+
}
|
|
105
|
+
await writeSavedLoginCredential(file, options);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=auth-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-session.js","sourceRoot":"","sources":["../src/auth-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { StorageDriver } from "@agent-issues/core";
|
|
2
|
+
export declare const BACKFILLABLE_BODY_KINDS: readonly ["project", "epic", "version", "initiative", "issue", "prd", "userStory", "adr"];
|
|
3
|
+
export type BackfillableBodyKind = (typeof BACKFILLABLE_BODY_KINDS)[number];
|
|
4
|
+
export type BackfillBodiesKindResult = {
|
|
5
|
+
kind: BackfillableBodyKind;
|
|
6
|
+
considered: number;
|
|
7
|
+
updated: number;
|
|
8
|
+
skipped: number;
|
|
9
|
+
};
|
|
10
|
+
export type BackfillBodiesResult = {
|
|
11
|
+
tenantId: string;
|
|
12
|
+
dryRun: boolean;
|
|
13
|
+
force: boolean;
|
|
14
|
+
kinds: BackfillableBodyKind[];
|
|
15
|
+
considered: number;
|
|
16
|
+
updated: number;
|
|
17
|
+
skipped: number;
|
|
18
|
+
byKind: BackfillBodiesKindResult[];
|
|
19
|
+
};
|
|
20
|
+
export declare function isBackfillableBodyKind(value: string): value is BackfillableBodyKind;
|
|
21
|
+
export declare function parseBackfillableBodyKinds(values: string[]): BackfillableBodyKind[];
|
|
22
|
+
export declare function backfillBodies(store: StorageDriver, input?: {
|
|
23
|
+
dryRun?: boolean;
|
|
24
|
+
force?: boolean;
|
|
25
|
+
kinds?: BackfillableBodyKind[];
|
|
26
|
+
}): Promise<BackfillBodiesResult>;
|