@mc1global/opencode-jarvis 0.8.1 → 0.10.0
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/dist/application/azure-sync/push-use-cases.d.ts +6 -1
- package/dist/application/azure-sync/push-use-cases.d.ts.map +1 -1
- package/dist/application/azure-sync/push-use-cases.js +31 -5
- package/dist/application/azure-sync/push-use-cases.js.map +1 -1
- package/dist/application/bootstrap/index.d.ts +1 -1
- package/dist/application/bootstrap/index.d.ts.map +1 -1
- package/dist/application/bootstrap/index.js +1 -1
- package/dist/application/bootstrap/index.js.map +1 -1
- package/dist/application/bootstrap/use-cases.d.ts +16 -2
- package/dist/application/bootstrap/use-cases.d.ts.map +1 -1
- package/dist/application/bootstrap/use-cases.js +66 -215
- package/dist/application/bootstrap/use-cases.js.map +1 -1
- package/dist/application/config/config-write-service.d.ts +86 -0
- package/dist/application/config/config-write-service.d.ts.map +1 -0
- package/dist/application/config/config-write-service.js +237 -0
- package/dist/application/config/config-write-service.js.map +1 -0
- package/dist/application/config/index.d.ts +2 -0
- package/dist/application/config/index.d.ts.map +1 -1
- package/dist/application/config/index.js +1 -0
- package/dist/application/config/index.js.map +1 -1
- package/dist/application/context-memory/execution-journal-use-cases.d.ts +69 -0
- package/dist/application/context-memory/execution-journal-use-cases.d.ts.map +1 -0
- package/dist/application/context-memory/execution-journal-use-cases.js +89 -0
- package/dist/application/context-memory/execution-journal-use-cases.js.map +1 -0
- package/dist/cli/config-wizard.d.ts +14 -0
- package/dist/cli/config-wizard.d.ts.map +1 -0
- package/dist/cli/config-wizard.js +120 -0
- package/dist/cli/config-wizard.js.map +1 -0
- package/dist/cli/section-editors.d.ts +33 -0
- package/dist/cli/section-editors.d.ts.map +1 -0
- package/dist/cli/section-editors.js +286 -0
- package/dist/cli/section-editors.js.map +1 -0
- package/dist/cli/wizard-prompts.d.ts +76 -0
- package/dist/cli/wizard-prompts.d.ts.map +1 -0
- package/dist/cli/wizard-prompts.js +98 -0
- package/dist/cli/wizard-prompts.js.map +1 -0
- package/dist/domain/azure-sync/value-objects.d.ts +10 -0
- package/dist/domain/azure-sync/value-objects.d.ts.map +1 -1
- package/dist/domain/azure-sync/value-objects.js +24 -0
- package/dist/domain/azure-sync/value-objects.js.map +1 -1
- package/dist/domain/config/index.d.ts +1 -1
- package/dist/domain/config/index.d.ts.map +1 -1
- package/dist/domain/config/repositories.d.ts +26 -6
- package/dist/domain/config/repositories.d.ts.map +1 -1
- package/dist/domain/config/repositories.js +6 -6
- package/dist/domain/context-memory/entities.d.ts +50 -2
- package/dist/domain/context-memory/entities.d.ts.map +1 -1
- package/dist/domain/context-memory/entities.js +92 -2
- package/dist/domain/context-memory/entities.js.map +1 -1
- package/dist/domain/context-memory/repositories.d.ts +15 -2
- package/dist/domain/context-memory/repositories.d.ts.map +1 -1
- package/dist/domain/context-memory/value-objects.d.ts +18 -1
- package/dist/domain/context-memory/value-objects.d.ts.map +1 -1
- package/dist/domain/context-memory/value-objects.js +39 -1
- package/dist/domain/context-memory/value-objects.js.map +1 -1
- package/dist/hooks/config-command.d.ts +37 -0
- package/dist/hooks/config-command.d.ts.map +1 -0
- package/dist/hooks/config-command.js +68 -0
- package/dist/hooks/config-command.js.map +1 -0
- package/dist/hooks/execution-journal.d.ts +40 -0
- package/dist/hooks/execution-journal.d.ts.map +1 -0
- package/dist/hooks/execution-journal.js +102 -0
- package/dist/hooks/execution-journal.js.map +1 -0
- package/dist/hooks/first-run-guide.d.ts +2 -0
- package/dist/hooks/first-run-guide.d.ts.map +1 -1
- package/dist/hooks/first-run-guide.js +9 -0
- package/dist/hooks/first-run-guide.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -3
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/azure-sync/azure-devops-client.d.ts.map +1 -1
- package/dist/infrastructure/azure-sync/azure-devops-client.js +9 -10
- package/dist/infrastructure/azure-sync/azure-devops-client.js.map +1 -1
- package/dist/infrastructure/config/index.d.ts +1 -0
- package/dist/infrastructure/config/index.d.ts.map +1 -1
- package/dist/infrastructure/config/index.js +1 -0
- package/dist/infrastructure/config/index.js.map +1 -1
- package/dist/infrastructure/config/yaml-config-writer.d.ts +16 -0
- package/dist/infrastructure/config/yaml-config-writer.d.ts.map +1 -0
- package/dist/infrastructure/config/yaml-config-writer.js +49 -0
- package/dist/infrastructure/config/yaml-config-writer.js.map +1 -0
- package/dist/infrastructure/context-memory/execution-journal-repository.d.ts +26 -0
- package/dist/infrastructure/context-memory/execution-journal-repository.d.ts.map +1 -0
- package/dist/infrastructure/context-memory/execution-journal-repository.js +110 -0
- package/dist/infrastructure/context-memory/execution-journal-repository.js.map +1 -0
- package/dist/tools/config-tools.d.ts +12 -0
- package/dist/tools/config-tools.d.ts.map +1 -0
- package/dist/tools/config-tools.js +136 -0
- package/dist/tools/config-tools.js.map +1 -0
- package/package.json +5 -2
- package/templates/agents-md.template.md +232 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-config-writer.js","sourceRoot":"","sources":["../../../src/infrastructure/config/yaml-config-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,IAAI,MAAM,SAAS,CAAC;AAG3B;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IACE;IAA7B,YAA6B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEjD,QAAQ,CAAC,IAA6B;QACpC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,kEAAkE;IAC1D,SAAS,CAAC,IAA6B;QAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACrB,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,GAAG;YACd,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,GAAG;YAChB,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Execution Journal Repository
|
|
3
|
+
*
|
|
4
|
+
* Implements ExecutionJournalRepository interface from domain layer.
|
|
5
|
+
* Maps ExecutionEntry entities to/from SQLite rows.
|
|
6
|
+
* Entry IDs are auto-increment integers assigned by SQLite.
|
|
7
|
+
*
|
|
8
|
+
* SOLID: SRP - persistence for ExecutionEntry only
|
|
9
|
+
* SOLID: DIP - implements domain interface
|
|
10
|
+
*/
|
|
11
|
+
import type { SqliteAdapter } from "../database/sqlite-adapter.js";
|
|
12
|
+
import type { ExecutionJournalRepository } from "../../domain/context-memory/repositories.js";
|
|
13
|
+
import { ExecutionEntry } from "../../domain/context-memory/entities.js";
|
|
14
|
+
import { ExecutionEntryId } from "../../domain/context-memory/value-objects.js";
|
|
15
|
+
import { WorkspaceId } from "../../domain/shared/value-objects.js";
|
|
16
|
+
export declare class SqliteExecutionJournalRepository implements ExecutionJournalRepository {
|
|
17
|
+
private readonly db;
|
|
18
|
+
constructor(db: SqliteAdapter);
|
|
19
|
+
save(entry: ExecutionEntry): Promise<ExecutionEntry>;
|
|
20
|
+
findById(id: ExecutionEntryId): Promise<ExecutionEntry | null>;
|
|
21
|
+
update(entry: ExecutionEntry): Promise<void>;
|
|
22
|
+
findRunning(workspace: WorkspaceId): Promise<readonly ExecutionEntry[]>;
|
|
23
|
+
pruneOlderThan(workspace: WorkspaceId, before: Date): Promise<number>;
|
|
24
|
+
private toDomain;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=execution-journal-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-journal-repository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/context-memory/execution-journal-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EACL,gBAAgB,EAGjB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,WAAW,EAAa,MAAM,sCAAsC,CAAC;AAmC9E,qBAAa,gCAAiC,YAAW,0BAA0B;IACrE,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAIxC,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IA8BpD,QAAQ,CAAC,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAQ9D,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5C,WAAW,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAQvE,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAa3E,OAAO,CAAC,QAAQ;CAoBjB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ExecutionEntry } from "../../domain/context-memory/entities.js";
|
|
2
|
+
import { ExecutionEntryId, ExecutionState, SessionId, } from "../../domain/context-memory/value-objects.js";
|
|
3
|
+
import { WorkspaceId, Timestamp } from "../../domain/shared/value-objects.js";
|
|
4
|
+
const SCHEMA_KEY = "context_memory_execution_journal";
|
|
5
|
+
const DDL = `
|
|
6
|
+
CREATE TABLE IF NOT EXISTS execution_journal (
|
|
7
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
8
|
+
tool_name TEXT NOT NULL,
|
|
9
|
+
args_summary TEXT NOT NULL DEFAULT '',
|
|
10
|
+
state TEXT NOT NULL DEFAULT 'running',
|
|
11
|
+
workspace TEXT NOT NULL,
|
|
12
|
+
session_id TEXT,
|
|
13
|
+
started_at TEXT NOT NULL,
|
|
14
|
+
finished_at TEXT,
|
|
15
|
+
error_message TEXT,
|
|
16
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
17
|
+
);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_execjournal_workspace ON execution_journal(workspace);
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_execjournal_state ON execution_journal(state);
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_execjournal_started_at ON execution_journal(started_at);
|
|
21
|
+
`;
|
|
22
|
+
export class SqliteExecutionJournalRepository {
|
|
23
|
+
db;
|
|
24
|
+
constructor(db) {
|
|
25
|
+
this.db = db;
|
|
26
|
+
this.db.ensureSchema(SCHEMA_KEY, DDL);
|
|
27
|
+
}
|
|
28
|
+
async save(entry) {
|
|
29
|
+
const sql = `
|
|
30
|
+
INSERT INTO execution_journal (tool_name, args_summary, state, workspace, session_id, started_at, finished_at, error_message)
|
|
31
|
+
VALUES (@tool_name, @args_summary, @state, @workspace, @session_id, @started_at, @finished_at, @error_message)
|
|
32
|
+
`;
|
|
33
|
+
const result = this.db.execute(sql, {
|
|
34
|
+
tool_name: entry.toolName,
|
|
35
|
+
args_summary: entry.argsSummary,
|
|
36
|
+
state: entry.state,
|
|
37
|
+
workspace: entry.workspace.value,
|
|
38
|
+
session_id: entry.sessionId?.value ?? null,
|
|
39
|
+
started_at: entry.startedAt.toISO(),
|
|
40
|
+
finished_at: entry.finishedAt?.toISO() ?? null,
|
|
41
|
+
error_message: entry.errorMessage ?? null,
|
|
42
|
+
});
|
|
43
|
+
const realId = Number(result.lastInsertRowid);
|
|
44
|
+
return ExecutionEntry.reconstitute({
|
|
45
|
+
id: ExecutionEntryId.create(realId),
|
|
46
|
+
toolName: entry.toolName,
|
|
47
|
+
argsSummary: entry.argsSummary,
|
|
48
|
+
state: entry.state,
|
|
49
|
+
workspace: entry.workspace,
|
|
50
|
+
...(entry.sessionId !== undefined ? { sessionId: entry.sessionId } : {}),
|
|
51
|
+
startedAt: entry.startedAt,
|
|
52
|
+
...(entry.finishedAt !== undefined ? { finishedAt: entry.finishedAt } : {}),
|
|
53
|
+
...(entry.errorMessage !== undefined ? { errorMessage: entry.errorMessage } : {}),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async findById(id) {
|
|
57
|
+
const row = this.db.queryOne("SELECT * FROM execution_journal WHERE id = @id", { id: id.numericValue });
|
|
58
|
+
return row != null ? this.toDomain(row) : null;
|
|
59
|
+
}
|
|
60
|
+
async update(entry) {
|
|
61
|
+
const sql = `
|
|
62
|
+
UPDATE execution_journal
|
|
63
|
+
SET state = @state, finished_at = @finished_at, error_message = @error_message
|
|
64
|
+
WHERE id = @id
|
|
65
|
+
`;
|
|
66
|
+
this.db.execute(sql, {
|
|
67
|
+
id: entry.id.numericValue,
|
|
68
|
+
state: entry.state,
|
|
69
|
+
finished_at: entry.finishedAt?.toISO() ?? null,
|
|
70
|
+
error_message: entry.errorMessage ?? null,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async findRunning(workspace) {
|
|
74
|
+
const rows = this.db.queryAll("SELECT * FROM execution_journal WHERE workspace = @workspace AND state = @state ORDER BY started_at DESC", { workspace: workspace.value, state: ExecutionState.Running });
|
|
75
|
+
return rows.map((row) => this.toDomain(row));
|
|
76
|
+
}
|
|
77
|
+
async pruneOlderThan(workspace, before) {
|
|
78
|
+
const sql = `
|
|
79
|
+
DELETE FROM execution_journal
|
|
80
|
+
WHERE workspace = @workspace AND state != @running AND started_at < @before
|
|
81
|
+
`;
|
|
82
|
+
const result = this.db.execute(sql, {
|
|
83
|
+
workspace: workspace.value,
|
|
84
|
+
running: ExecutionState.Running,
|
|
85
|
+
before: before.toISOString(),
|
|
86
|
+
});
|
|
87
|
+
return result.changes;
|
|
88
|
+
}
|
|
89
|
+
toDomain(row) {
|
|
90
|
+
const props = {
|
|
91
|
+
id: ExecutionEntryId.create(row.id),
|
|
92
|
+
toolName: row.tool_name,
|
|
93
|
+
argsSummary: row.args_summary,
|
|
94
|
+
state: row.state,
|
|
95
|
+
workspace: WorkspaceId.from(row.workspace),
|
|
96
|
+
...(row.session_id !== null
|
|
97
|
+
? { sessionId: SessionId.from(row.session_id) }
|
|
98
|
+
: {}),
|
|
99
|
+
startedAt: Timestamp.fromISO(row.started_at),
|
|
100
|
+
...(row.finished_at !== null
|
|
101
|
+
? { finishedAt: Timestamp.fromISO(row.finished_at) }
|
|
102
|
+
: {}),
|
|
103
|
+
...(row.error_message !== null
|
|
104
|
+
? { errorMessage: row.error_message }
|
|
105
|
+
: {}),
|
|
106
|
+
};
|
|
107
|
+
return ExecutionEntry.reconstitute(props);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=execution-journal-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-journal-repository.js","sourceRoot":"","sources":["../../../src/infrastructure/context-memory/execution-journal-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@opencode-ai/plugin";
|
|
2
|
+
import type { ConfigService } from "../application/config/config-service.js";
|
|
3
|
+
import type { ConfigWriteService } from "../application/config/config-write-service.js";
|
|
4
|
+
export interface ConfigToolsDeps {
|
|
5
|
+
readonly configService: ConfigService;
|
|
6
|
+
readonly configWriteService: ConfigWriteService;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates config read/write tools for agent-guided configuration.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createConfigTools(deps: ConfigToolsDeps): Record<string, ToolDefinition>;
|
|
12
|
+
//# sourceMappingURL=config-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-tools.d.ts","sourceRoot":"","sources":["../../src/tools/config-tools.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AAOxF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CACjD;AAID;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,GACpB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyGhC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Tools
|
|
3
|
+
*
|
|
4
|
+
* OpenCode tool definitions for reading and writing JARVIS configuration.
|
|
5
|
+
* Provides agent-accessible tools for the /config slash command and
|
|
6
|
+
* general config management within OpenCode sessions.
|
|
7
|
+
*
|
|
8
|
+
* Tools defined (2):
|
|
9
|
+
* config-read — Read current effective config for a section or all sections
|
|
10
|
+
* config-write — Update config values for a specific section
|
|
11
|
+
*
|
|
12
|
+
* SOLID: SRP — config tool exposure only
|
|
13
|
+
* SOLID: DIP — depends on use case abstractions
|
|
14
|
+
*/
|
|
15
|
+
import { tool } from "@opencode-ai/plugin";
|
|
16
|
+
const z = tool.schema;
|
|
17
|
+
// ── Tool Factory ──────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Creates config read/write tools for agent-guided configuration.
|
|
20
|
+
*/
|
|
21
|
+
export function createConfigTools(deps) {
|
|
22
|
+
const { configService, configWriteService } = deps;
|
|
23
|
+
// ── config-read ──────────────────────────────────────────────────
|
|
24
|
+
const configRead = tool({
|
|
25
|
+
description: "Read current effective JARVIS configuration. Without a section argument, " +
|
|
26
|
+
"returns all writable sections with their current effective values (defaults merged " +
|
|
27
|
+
"with user overrides). With a section argument, returns that section's full config. " +
|
|
28
|
+
"Shows which values are overridden vs defaults.",
|
|
29
|
+
args: {
|
|
30
|
+
section: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Config section to read (e.g., 'rag', 'azure-sync', 'pipeline', " +
|
|
34
|
+
"'agent-registry', 'mcp-server', 'kanban', 'token-metrics'). " +
|
|
35
|
+
"Omit to read all sections."),
|
|
36
|
+
},
|
|
37
|
+
async execute(args) {
|
|
38
|
+
const writableContexts = configWriteService.getWritableContexts();
|
|
39
|
+
if (args.section !== undefined) {
|
|
40
|
+
if (!writableContexts.includes(args.section)) {
|
|
41
|
+
return `Unknown or non-writable section: "${args.section}"\n\nWritable sections: ${writableContexts.join(", ")}`;
|
|
42
|
+
}
|
|
43
|
+
const effective = configService.getConfig(args.section);
|
|
44
|
+
return formatConfigSection(args.section, effective);
|
|
45
|
+
}
|
|
46
|
+
// All sections
|
|
47
|
+
const lines = [
|
|
48
|
+
"JARVIS Configuration — All Sections",
|
|
49
|
+
`External config file: ${configService.isExternalConfigAvailable() ? "found" : "not found (using defaults only)"}`,
|
|
50
|
+
"",
|
|
51
|
+
];
|
|
52
|
+
for (const ctx of writableContexts) {
|
|
53
|
+
const effective = configService.getConfig(ctx);
|
|
54
|
+
lines.push(formatConfigSection(ctx, effective));
|
|
55
|
+
lines.push("");
|
|
56
|
+
}
|
|
57
|
+
return lines.join("\n");
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
// ── config-write ─────────────────────────────────────────────────
|
|
61
|
+
const configWrite = tool({
|
|
62
|
+
description: "Update JARVIS configuration values for a specific section. " +
|
|
63
|
+
"Accepts a JSON object with the values to change. Only values that " +
|
|
64
|
+
"differ from defaults are persisted to config/jarvis.yaml. " +
|
|
65
|
+
"Validates input before writing (e.g., pollEnabled requires org+project).",
|
|
66
|
+
args: {
|
|
67
|
+
section: z
|
|
68
|
+
.string()
|
|
69
|
+
.describe("Config section to update (e.g., 'azure-sync', 'rag', 'pipeline', " +
|
|
70
|
+
"'agent-registry', 'mcp-server', 'kanban', 'token-metrics')."),
|
|
71
|
+
values: z
|
|
72
|
+
.string()
|
|
73
|
+
.describe("JSON string of the partial values to update. " +
|
|
74
|
+
'Example: \'{"organization": "MyOrg", "project": "MyProject"}\' for azure-sync. ' +
|
|
75
|
+
"Only include the keys you want to change."),
|
|
76
|
+
},
|
|
77
|
+
async execute(args) {
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = JSON.parse(args.values);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return `Error: Invalid JSON in values parameter: ${args.values}`;
|
|
84
|
+
}
|
|
85
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
86
|
+
return "Error: values must be a JSON object (not array or primitive)";
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const effective = configWriteService.updateContext(args.section, parsed);
|
|
90
|
+
return (`Configuration updated for "${args.section}".\n\n` +
|
|
91
|
+
`New effective values:\n${formatConfigSection(args.section, effective)}`);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
95
|
+
return `Error updating "${args.section}": ${msg}`;
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
"config-read": configRead,
|
|
101
|
+
"config-write": configWrite,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// ── Formatting Helpers ────────────────────────────────────────────────
|
|
105
|
+
function formatConfigSection(name, config) {
|
|
106
|
+
const lines = [`[${name}]`];
|
|
107
|
+
if (config === null || config === undefined) {
|
|
108
|
+
lines.push(" (no configuration)");
|
|
109
|
+
return lines.join("\n");
|
|
110
|
+
}
|
|
111
|
+
if (typeof config !== "object") {
|
|
112
|
+
lines.push(` ${String(config)}`);
|
|
113
|
+
return lines.join("\n");
|
|
114
|
+
}
|
|
115
|
+
formatObject(config, lines, 1);
|
|
116
|
+
return lines.join("\n");
|
|
117
|
+
}
|
|
118
|
+
function formatObject(obj, lines, depth) {
|
|
119
|
+
const indent = " ".repeat(depth);
|
|
120
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
121
|
+
if (value === null) {
|
|
122
|
+
lines.push(`${indent}${key}: null`);
|
|
123
|
+
}
|
|
124
|
+
else if (typeof value === "object" && !Array.isArray(value)) {
|
|
125
|
+
lines.push(`${indent}${key}:`);
|
|
126
|
+
formatObject(value, lines, depth + 1);
|
|
127
|
+
}
|
|
128
|
+
else if (Array.isArray(value)) {
|
|
129
|
+
lines.push(`${indent}${key}: [${value.map((v) => JSON.stringify(v)).join(", ")}]`);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
lines.push(`${indent}${key}: ${String(value)}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=config-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-tools.js","sourceRoot":"","sources":["../../src/tools/config-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mc1global/opencode-jarvis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "JARVIS Framework - OpenCode native plugin for multi-agent development with DDD architecture",
|
|
5
5
|
"author": "Julio Fabio de O. Chagas <julio.fabio@mc1global.com>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -15,10 +15,12 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"bin": {
|
|
18
|
-
"jarvis-mcp": "dist/mcp-server.js"
|
|
18
|
+
"jarvis-mcp": "dist/mcp-server.js",
|
|
19
|
+
"jarvis": "dist/cli/config-wizard.js"
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
22
|
"dist/",
|
|
23
|
+
"templates/",
|
|
22
24
|
"LICENSE",
|
|
23
25
|
"README.md",
|
|
24
26
|
"QUICK-GUIDE.md"
|
|
@@ -45,6 +47,7 @@
|
|
|
45
47
|
"@opencode-ai/plugin": ">=1.1.0"
|
|
46
48
|
},
|
|
47
49
|
"dependencies": {
|
|
50
|
+
"@clack/prompts": "^1.0.1",
|
|
48
51
|
"@langchain/textsplitters": "^1.0.1",
|
|
49
52
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
50
53
|
"js-yaml": "^4.1.1",
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# AGENTS.md — JARVIS Plugin Operational Guide
|
|
2
|
+
|
|
3
|
+
This file instructs agentic coding agents operating in this repository.
|
|
4
|
+
JARVIS is an OpenCode plugin implementing a multi-agent development framework
|
|
5
|
+
with kanban governance, context memory, automatic cost tracking, and CI/CD
|
|
6
|
+
pipeline support.
|
|
7
|
+
|
|
8
|
+
## Architecture Constraints — Inviolable
|
|
9
|
+
|
|
10
|
+
- **SOLID Principles** — Every class/module must strictly respect all 5 principles
|
|
11
|
+
- **Domain-Driven Design** — Domain layer has ZERO external dependencies. Repository
|
|
12
|
+
interfaces in domain, implementations in infrastructure
|
|
13
|
+
- **Max 500 lines per file** — No exceptions. Split by responsibility if approaching limit
|
|
14
|
+
- **ESM modules** — `"type": "module"` required by `@opencode-ai/plugin`
|
|
15
|
+
- **Strict TypeScript** — `exactOptionalPropertyTypes`, `verbatimModuleSyntax`,
|
|
16
|
+
`noUncheckedIndexedAccess` all enabled
|
|
17
|
+
- **13 bounded contexts** with strict DDD boundaries — no direct imports between contexts
|
|
18
|
+
- **Cross-context communication** via ports/callbacks wired at composition root
|
|
19
|
+
|
|
20
|
+
## Mandatory Workflow — Kanban Lifecycle
|
|
21
|
+
|
|
22
|
+
ALL non-trivial work (>15 minutes) MUST follow the full kanban pipeline.
|
|
23
|
+
Do NOT skip steps. Do NOT commit directly to `main`.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
backlog -> grooming -> ready -> doing -> review -> tested -> done
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Before coding anything:
|
|
30
|
+
|
|
31
|
+
1. **Create or pick a card** — `kanban-card-create`, assign to epic and sprint
|
|
32
|
+
2. **Groom it** — Write a scope doc in `obsidian-vault/12-Scope-Docs/`, define
|
|
33
|
+
acceptance criteria (min 2), estimate story points (Fibonacci), assign epic
|
|
34
|
+
3. **Move to ready** — Card cannot leave grooming without: scope doc, AC, points, epic
|
|
35
|
+
4. **Assign agent + sprint** — Then move to `doing`
|
|
36
|
+
5. **Start a session** — `context-session-start` before any card work
|
|
37
|
+
|
|
38
|
+
### Grooming rules — CRITICAL:
|
|
39
|
+
|
|
40
|
+
Grooming defines **problem, value, and boundaries**. It does NOT prescribe
|
|
41
|
+
implementation details (no class names, method signatures, field names, code
|
|
42
|
+
snippets). The implementing agent decides those during the `doing` phase.
|
|
43
|
+
|
|
44
|
+
### After coding:
|
|
45
|
+
|
|
46
|
+
6. **Run tests + linter** — All must pass, zero errors
|
|
47
|
+
7. **Commit** — Imperative mood, reference card: `Add X (CD-XXX)` or `Fix Y (CD-XXX)`
|
|
48
|
+
8. **Move card** — `doing -> review -> tested -> done`, meet all AC and gate tasks first
|
|
49
|
+
9. **Update vault** — Dashboard + domain reference doc at end of every phase
|
|
50
|
+
|
|
51
|
+
## Guardrails — Hard Rules
|
|
52
|
+
|
|
53
|
+
### NEVER:
|
|
54
|
+
- Use fallback/mock behavior to mask errors — errors must throw with proper handling
|
|
55
|
+
- Use a "simpler approach" to bypass the real solution
|
|
56
|
+
- Read `.csv` directly — use `data-csv-query` tool
|
|
57
|
+
- Read `.yaml/.yml` directly — use `data-yaml-get` tool
|
|
58
|
+
- Read `.env`, `.pem`, `.key`, credentials files — blocked by governance
|
|
59
|
+
- Run `git push --force` on main/master
|
|
60
|
+
- Run `sqlite3` CLI — use repository methods
|
|
61
|
+
- Create `TODO.md`, `PLAN.md`, or `ROADMAP.md` — use kanban tools
|
|
62
|
+
- Bypass the kanban pipeline for trackable work
|
|
63
|
+
- Push to git without explicit user approval
|
|
64
|
+
- Start the app from the agent session — ask the user to do it in another terminal
|
|
65
|
+
- Skip grooming requirements or gate tasks for cards
|
|
66
|
+
- Import directly between bounded contexts — use ports/callbacks
|
|
67
|
+
|
|
68
|
+
### ALWAYS:
|
|
69
|
+
- Search RAG (`rag-search` / `rag-snippet`) before creating or modifying files
|
|
70
|
+
- Use specialized tools instead of raw file operations
|
|
71
|
+
- Get full codebase context before making changes — ask if unclear
|
|
72
|
+
- Validate card status transitions through the kanban domain
|
|
73
|
+
- Track context with sessions, TODOs, and notes
|
|
74
|
+
- Meet all gate tasks before moving cards through review/tested/done
|
|
75
|
+
|
|
76
|
+
## Governance Policies (13 Runtime Enforced)
|
|
77
|
+
|
|
78
|
+
Governance policies are evaluated by the `tool.execute.before` hook on every
|
|
79
|
+
tool invocation. Violations with `error` severity throw and block execution.
|
|
80
|
+
|
|
81
|
+
Policy groups:
|
|
82
|
+
- **File access** — Block direct CSV, YAML, env file reads (use specialized tools)
|
|
83
|
+
- **Shell safety** — Block force push, direct SQLite CLI, warn on destructive ops
|
|
84
|
+
- **Security** — Block env dump, sensitive file reads, credential file access
|
|
85
|
+
- **Pipeline** — Warn when running pipeline without linked card
|
|
86
|
+
- **Kanban** — Require gate tasks before status transitions, warn on rapid transitions
|
|
87
|
+
|
|
88
|
+
Use `governance-validate` to pre-check if an operation is allowed.
|
|
89
|
+
Use `governance-policies` to list all active policies.
|
|
90
|
+
|
|
91
|
+
{{#IF CONTAINER_USE}}
|
|
92
|
+
## Container-Use Environments
|
|
93
|
+
|
|
94
|
+
Container-use environments are isolated containers with their own git worktree
|
|
95
|
+
branches. Use them for all file, code, and shell operations.
|
|
96
|
+
|
|
97
|
+
Workflow:
|
|
98
|
+
1. `env-init` — Detect project stack
|
|
99
|
+
2. `env-create` — Spin up container from git ref
|
|
100
|
+
3. Work inside container via `container-use_environment_*` tools
|
|
101
|
+
4. `env-merge` — Merge branch back to main
|
|
102
|
+
5. `env-delete` — Clean up container + worktree
|
|
103
|
+
|
|
104
|
+
IMPORTANT: Always inform the user how to view your work using
|
|
105
|
+
`container-use log <env_id>` and `container-use checkout <env_id>`.
|
|
106
|
+
|
|
107
|
+
Do NOT install or use the git CLI with `environment_run_cmd`. All environment
|
|
108
|
+
tools handle git operations automatically.
|
|
109
|
+
{{/IF CONTAINER_USE}}
|
|
110
|
+
|
|
111
|
+
{{#IF AZURE_SYNC}}
|
|
112
|
+
## Azure DevOps Integration
|
|
113
|
+
|
|
114
|
+
This project is connected to Azure DevOps ({{AZURE_ORG}}/{{AZURE_PROJECT}}).
|
|
115
|
+
|
|
116
|
+
Available tools:
|
|
117
|
+
- `azure-sync-discover` — Detect project template, list work items + iterations
|
|
118
|
+
- `azure-sync-push` — Push cards/epics/sprints to Azure DevOps
|
|
119
|
+
- `azure-sync-pull` — Pull work items from Azure DevOps
|
|
120
|
+
- `azure-sync-sync` — Bidirectional sync (push then pull)
|
|
121
|
+
- `azure-sync-status` — Show sync status between local and Azure
|
|
122
|
+
- `azure-sync-config` — Show configuration + test connectivity
|
|
123
|
+
- `azure-sync-events` — List/acknowledge/dismiss detected change events
|
|
124
|
+
- `azure-sync-poll-status` — Show background poll service status
|
|
125
|
+
- `azure-pr-create` — Create Pull Request in Azure Repos
|
|
126
|
+
- `azure-pr-list` — List Pull Requests
|
|
127
|
+
|
|
128
|
+
Poll service can be enabled in `config/jarvis.yaml` under `azure-sync.pollEnabled`
|
|
129
|
+
to automatically detect changes made by team members in Azure DevOps.
|
|
130
|
+
{{/IF AZURE_SYNC}}
|
|
131
|
+
|
|
132
|
+
{{#IF PIPELINE}}
|
|
133
|
+
## CI/CD Pipelines (Dagger)
|
|
134
|
+
|
|
135
|
+
Pipeline BC uses Dagger for CI/CD gate execution. Pipelines are created from
|
|
136
|
+
stack templates (typescript-lib, python-app, etc.) and run gates in containers.
|
|
137
|
+
|
|
138
|
+
Workflow:
|
|
139
|
+
1. `pipeline-init` — Create pipeline from stack template
|
|
140
|
+
2. `pipeline-activate` — Make pipeline runnable
|
|
141
|
+
3. `pipeline-run` — Execute gates via Dagger
|
|
142
|
+
4. `pipeline-gate` — Manual pass/fail/skip/retry for gates
|
|
143
|
+
5. `pipeline-status` — View pipeline state and gate results
|
|
144
|
+
|
|
145
|
+
Templates available via `pipeline-template` tool.
|
|
146
|
+
Scaffold Dagger modules via `pipeline-scaffold` tool.
|
|
147
|
+
{{/IF PIPELINE}}
|
|
148
|
+
|
|
149
|
+
## Obsidian Vault
|
|
150
|
+
|
|
151
|
+
Documentation lives in `obsidian-vault/`. Use structured lists, NOT markdown
|
|
152
|
+
tables (token efficiency). Update at end of every phase:
|
|
153
|
+
|
|
154
|
+
- `09-Dashboards/` — Project dashboards and metrics
|
|
155
|
+
- `11-Domain-Reference/` — Per-context architecture docs
|
|
156
|
+
- `12-Scope-Docs/CD-XXX-*.md` — Grooming scope documents
|
|
157
|
+
|
|
158
|
+
Use `vault-manage` tool for smart vault operations (inspect, read, write, create,
|
|
159
|
+
search, table-read, table-update).
|
|
160
|
+
|
|
161
|
+
## Git Strategy
|
|
162
|
+
|
|
163
|
+
- Work on feature branches (never commit directly to `main`)
|
|
164
|
+
- Commit messages: imperative verb + summary + card reference
|
|
165
|
+
- `Add feature X (CD-001)`
|
|
166
|
+
- `Fix bug Y (CD-015)`
|
|
167
|
+
- Merge via PR or controlled merge
|
|
168
|
+
- Never amend pushed commits without explicit request
|
|
169
|
+
- Never push without explicit user approval
|
|
170
|
+
|
|
171
|
+
## Configuration System
|
|
172
|
+
|
|
173
|
+
`config/jarvis.yaml` holds tunable settings per bounded context. The ConfigService
|
|
174
|
+
deep-merges YAML overrides over hardcoded defaults. Access config via the
|
|
175
|
+
appropriate getter methods — never read YAML files directly.
|
|
176
|
+
|
|
177
|
+
Available config sections: `rag`, `azure-sync`, `kanban`, `mcp-server`,
|
|
178
|
+
`pipeline`, `token-metrics` (with `sprintBudgetUsd` and `budgetAlertThreshold`).
|
|
179
|
+
|
|
180
|
+
## Tool Quick Reference (113 tools)
|
|
181
|
+
|
|
182
|
+
JARVIS provides 113 tools across 13 bounded contexts. Key tool groups:
|
|
183
|
+
|
|
184
|
+
- **Context Memory** (8): `context-session-start`, `context-session-finish`, `context-todo-add`, `context-note-add`, `context-search`...
|
|
185
|
+
- **Kanban** (31): `kanban-card-create`, `kanban-card-move`, `kanban-board-view`, `kanban-sprint-create`, `kanban-epic-create`, `kanban-grooming-validate`, `kanban-card-gate`...
|
|
186
|
+
- **Governance** (2): `governance-validate`, `governance-policies`
|
|
187
|
+
- **Token Metrics** (7): `metrics-summary`, `metrics-agent-report`, `metrics-card-report`, `metrics-sprint-report`, `metrics-estimate`... (auto-tracks cost per card/sprint)
|
|
188
|
+
- **Vault** (11): `vault-manage` (smart facade), `vault-doc-create`, `vault-doc-search`...
|
|
189
|
+
- **RAG** (8): `rag-search`, `rag-snippet`, `rag-index`, `rag-oracle-search`, `rag-oracle-index`...
|
|
190
|
+
- **Data** (3): `data-yaml-get`, `data-json-get`, `data-csv-query`
|
|
191
|
+
- **Agent** (8): `agent-sessions`, `agent-send`, `agent-spawn`, `agent-dispatch`, `agent-register`, `agent-profile`...
|
|
192
|
+
- **Pipeline** (10): `pipeline-init`, `pipeline-run`, `pipeline-status`, `pipeline-template`, `pipeline-scaffold`...
|
|
193
|
+
- **Environment** (6): `env-init`, `env-create`, `env-list`, `env-status`, `env-merge`, `env-delete`
|
|
194
|
+
- **Workspace** (4): `workspace-info`, `workspace-list`, `workspace-update`, `workspace-link`
|
|
195
|
+
- **Azure Sync** (10): `azure-sync-discover`, `azure-sync-push`, `azure-sync-pull`, `azure-sync-sync`, `azure-pr-create`...
|
|
196
|
+
- **Bootstrap** (3): `jarvis-bootstrap`, `jarvis-healthcheck`, `jarvis-terminal-commands`
|
|
197
|
+
- **Domain Map** (2): `domain-map-analyze`, `domain-map-view`
|
|
198
|
+
|
|
199
|
+
For detailed workflows, load the appropriate skill (see below).
|
|
200
|
+
|
|
201
|
+
## Available Skills
|
|
202
|
+
|
|
203
|
+
Load skills via the `skill()` tool to get detailed workflow instructions:
|
|
204
|
+
|
|
205
|
+
- **`jarvis-kanban`** — Full kanban lifecycle: card creation, grooming, sprint management, gate tasks
|
|
206
|
+
- **`jarvis-azure-sync`** — Azure DevOps sync: push/pull/bidi-sync, PR creation, poll events
|
|
207
|
+
- **`jarvis-onboarding`** — Setup, healthcheck, RAG indexing, tool group reference
|
|
208
|
+
|
|
209
|
+
### Available Commands
|
|
210
|
+
|
|
211
|
+
Use these slash commands for common operations:
|
|
212
|
+
|
|
213
|
+
- **`/healthcheck`** — Run diagnostics and get actionable fix guidance
|
|
214
|
+
- **`/sync-azure`** — Execute Azure DevOps sync workflow
|
|
215
|
+
- **`/start-card CD-XXX`** — Start working on a specific card (handles full lifecycle)
|
|
216
|
+
|
|
217
|
+
When you encounter an unfamiliar workflow, ALWAYS load the relevant skill first.
|
|
218
|
+
|
|
219
|
+
## Knowledge Search — RAG & ORACLE
|
|
220
|
+
|
|
221
|
+
Before creating or modifying code, ALWAYS search first:
|
|
222
|
+
|
|
223
|
+
- **`rag-search`** / **`rag-snippet`** — Search the codebase semantically
|
|
224
|
+
- **`rag-oracle-search`** — Search curated framework documentation (governance, workflows, patterns)
|
|
225
|
+
|
|
226
|
+
When you don't know how to do something, search ORACLE:
|
|
227
|
+
```
|
|
228
|
+
rag-oracle-search query="how to sync azure devops"
|
|
229
|
+
rag-oracle-search query="kanban grooming requirements" domain="workflows"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
ORACLE domains: `governance`, `workflows`, `patterns`, `quick_reference`.
|